方法实例详解,javascript设置和获取cookie的方法实例详解

javascript设置和获取cookie的方法实例详解,javascriptcookie

本文实例讲述了javascript设置和获取cookie的方法。分享给大家供大家参考,具体如下:

  1. 设置cookie

    function setCookie(cookieName,cookieValue,cookieExpires,cookiePath)
    {
    cookieValue = escape(cookieValue);//编码latin-1
    if(cookieExpires==””)
    {

     var nowDate = new Date();
     nowDate.setMonth(nowDate.getMonth()+6);
     cookieExpires = nowDate.toGMTString();
    

    }
    if(cookiePath!=””)
    {

     cookiePath = ";Path="+cookiePath;
    

    }
    document.cookie= cookieName+”=”+cookieValue+”;expires=”+cookieExpires+cookiePath;
    }

  2. 获取cookie

    function getCookieValue(cookieName)
    {
    var cookieValue = document.cookie;
    var cookieStartAt = cookieValue.indexOf(“”+cookieName+”=”);
    if(cookieStartAt==-1)
    {

     cookieStartAt = cookieValue.indexOf(cookieName+"=");
    

    }
    if(cookieStartAt==-1)
    {

     cookieValue = null;
    

    }
    else
    {

     cookieStartAt = cookieValue.indexOf("=",cookieStartAt)+1;
     cookieEndAt = cookieValue.indexOf(";",cookieStartAt);
     if(cookieEndAt==-1)
     {
       cookieEndAt = cookieValue.length;
     }
     cookieValue = unescape(cookieValue.substring(cookieStartAt,cookieEndAt));//解码latin-1
    

    }
    return cookieValue;
    }

例子:

<!doctype html>
<html>
<head>
<title>cookie</title>
<meta charset="utf-8">
<script language="javascript" type="text/javascript">
  //获取cookie
   function getCookieValue(cookieName)
  {
    var cookieValue = document.cookie;
    var cookieStartAt = cookieValue.indexOf(""+cookieName+"=");
    if(cookieStartAt==-1)
    {
      cookieStartAt = cookieValue.indexOf(cookieName+"=");
    }
    if(cookieStartAt==-1)
    {
      cookieValue = null;
    }
    else
    {
      cookieStartAt = cookieValue.indexOf("=",cookieStartAt)+1;
      cookieEndAt = cookieValue.indexOf(";",cookieStartAt);
      if(cookieEndAt==-1)
      {
        cookieEndAt = cookieValue.length;
      }
      cookieValue = unescape(cookieValue.substring(cookieStartAt,cookieEndAt));//解码latin-1
    }
    return cookieValue;
  }
  //设置cookie
  function setCookie(cookieName,cookieValue,cookieExpires,cookiePath)
  {
    cookieValue = escape(cookieValue);//编码latin-1
    if(cookieExpires=="")
    {
      var nowDate = new Date();
      nowDate.setMonth(nowDate.getMonth()+6);
      cookieExpires = nowDate.toGMTString();
    }
    if(cookiePath!="")
    {
      cookiePath = ";Path="+cookiePath;
    }
    document.cookie= cookieName+"="+cookieValue+";expires="+cookieExpires+cookiePath;
  }
  //页面加载时间处理函数
  function window_onload()
  {
    var userNameElem = document.getElementById("userName");//用户名输入框对象
    var passwordElem = document.getElementById("password");//密码输入框对象
    var currUserElem = document.getElementById("currUser");//复选框对象
    var currUser = getCookieValue("currUser");
    if(currUser!=null)
    {
      userNameElem.value=currUser;
      currUserElem.checked = true;
    }
    if(userNameElem.value!="")
    {
      passwordElem.focus();//密码输入框获得焦点
    }
    else
    {
      currUserElem.focus();//用户名输入框获得焦点
    }
  }
  //表单提交处理
  function login()
  {
    var userNameElem = document.getElementById("userName");
    var passwordElem = document.getElementById("password");
    var currUserElem = document.getElementById("currUser");
    if(userNameElem.value=="" || passwordElem.value=="")
    {
      alert("用户名或密码不能为空!");
      if(userNameElem.value=="")
      {
        userNameElem.focus();//用户名输入框获得焦点
      }
      else
      {
        passwordElem.focus();//密码输入框获得焦点
      }
      return false;
    }
    if(currUserElem.checked)
    {
      setCookie("currUser",userNameElem.value,"","");//设置cookie
    }
    else
    {
      var nowDate = new Date();//当前日期
      nowDate.setMonth(nowDate.getMonth()-2);//将cookie的过期时间设置为之前的某个日期
      cookieExpires = nowDate.toGMTString();//过期时间的格式必须是GMT日期的格式
      setCookie("userName","",cookieExpires,"");//删除一个cookie只要将过期时间设置为过去的一个时间即可
    }
    return true;
  }
</script>
<style type="text/css">
  div{
    font-size:12px;
  }
</style>
</head>
<body onload="window_onload()">
<div>
<form id="loginForm" onsubmit="return login()">
用户名:<input type="text" id="userName"><br>
密 码:<input type="password" id="password">
<input type="checkbox" id="currUser">记住用户名<br>
<input type="submit" value="登录">
</form>
</div>
</body>
</html>

注意:

由于google
Chrome浏览器为了安全只支持online-cookie,所以在本地测试时是没有效果的,需要上传到服务器试一下。

更多关于JavaScript操作cookie相关内容可查看本站专题:《JavaScript 操作
cookie相关知识汇总》及《jQuery的cookie操作技巧总结》

希望本文所述对大家JavaScript程序设计有所帮助。

MySQL新特性之mysql_config_editor源码解析

从mysql5.6开始,mysql推出了加密工具mysql_config_editor。在此之前我们通过将账号和密码明文放入my.cnf,从而使用mysql客户端登录时,无需指定账号密码就可以登录数据库。而有了mysql_config_editor工具之后,我们将加密后的账号密码放入二进制文件。在登录时,客户端通过解密该文件来登录数据库。由于加密解密都在内存中进行,所以无法明文的显示文件内容。只要我们将文件权限保存好,就可以防止不怀好意的人解密我们的数据库密码了.

mysql_config_editor的使用过程如下: mysql_config_editor set
–login-path=client –host=localhost –user=localuser –password

这样我们就配置了一个为本地的数据源信息: login-path
:指定通过mysql客户端登录时的标识host:我们要连接的数据库user:
通过本地连接数据库时,使用的账号password:指定通过本地连接时,使用的数据库密码(这里假设输入的密码为password1)

当然,如果通过远程连接,我们可能还要加上特定的端口信息。这样,当我们登录数据库时,只需要如下命令就可以连接到该数据库了:mysql
—login-path=client
这样我们就连接到本地数据库了。
下面我们来看看mysql_config_editor的细节部分:
由于该工具包含set/remove/print/reset/help,所以我们仅分析set功能的实现:
set功能是通过set_command函数实现的,该函数主要用于配置账号密码等数据源信息,并将该信息存储到二进制文件:

static int set_command(void)
 {
DBUG_ENTER("set_command");

DYNAMIC_STRING file_buf, path_buf;
init_dynamic_string(&path_buf, "", MY_LINE_MAX, MY_LINE_MAX);
init_dynamic_string(&file_buf, "", file_size, 3 * MY_LINE_MAX);

if (tty_password)
opt_password= get_tty_password(NullS); 
if (file_size)
{
if (read_and_decrypt_file(&file_buf) == -1) //如果文件存在,就读取文件,并将文件的密文解密后存放到file_buf中.
goto error;
}

dynstr_append(&path_buf, "["); /* --login=path */ 
if (opt_login_path)
dynstr_append(&path_buf, opt_login_path);
else
dynstr_append(&path_buf, "client");
dynstr_append(&path_buf, "]");

if (opt_user) /* --user */
{
dynstr_append(&path_buf, "\nuser = ");
dynstr_append(&path_buf, opt_user);
}

if (opt_password) /* --password */
{
dynstr_append(&path_buf, "\npassword = ");
dynstr_append(&path_buf, opt_password);
}

if (opt_host) /* --host */
{
dynstr_append(&path_buf, "\nhost = ");
dynstr_append(&path_buf, opt_host);
}

if (opt_socket)
{
dynstr_append(&path_buf, "\nsocket = ");
dynstr_append(&path_buf, opt_socket);
}

if (opt_port)
{
dynstr_append(&path_buf, "\nport = ");
dynstr_append(&path_buf, opt_port);
}

dynstr_append(&path_buf, "\n");

/* Warn if login path already exists */
if (opt_warn && ((locate_login_path (&file_buf, opt_login_path)) //判断该login-path是否已经存在
!= NULL))
{
int choice;
printf ("WARNING : \'%s\' path already exists and will be "
"overwritten. \n Continue? (Press y|Y for Yes, any "
"other key for No) : ",
opt_login_path);
choice= getchar();

if (choice != (int) 'y' && choice != (int) 'Y’) //如果login-path存在是否选择覆盖
goto done; /* skip */
}

/* Remove the login path. */
remove_login_path(&file_buf, opt_login_path); //从原来文件中读取的内容中,删掉该login-path信息

/* Append the new login path to the file buffer. */
dynstr_append(&file_buf, path_buf.str); //将该login-path的信息加到file_buf的末尾

if (encrypt_and_write_file(&file_buf) == -1) //将包含新的log-path的所有信息和原来的信息加密写入文件
goto error;

done:
dynstr_free(&file_buf);
dynstr_free(&path_buf);
DBUG_RETURN(0);

error:
dynstr_free(&file_buf);
dynstr_free(&path_buf);
DBUG_RETURN(-1);
} 

代码的具体逻辑如下:
图片 1

在这里我们重点看看其中涉及的几个重要的函数:read_and_decrypt_file
(读取文件内容,并解密后放到动态字符缓冲中)locate_login_path(判断该login-path是否已经存在)remove_login_path(如果login-path存在,则删除该login-path)dynstr_append(&file_buf,
path_buf.str); 将新的login-path添加到file_buf
末尾encrypt_and_write_file(&file_buf)
将file_buf中的信息解码后写入到文件中

首先我们来看看加密后的文件格式如下:图片 2

这里我们假设之前已经存在加密的文件了.由于加密文件的前4个byte为’\0’,是未使用的,所以跳过解密环节。之后,紧接着的20个bytes是存放的对称加密算法的秘钥,而这部分内容在read_and_decrypt_file(read_login_key获取)调用之前已经读取取到,所以也要跳过。因此read_and_decrypt_file的过程如下:

/*
 Header length for the login file.
4-byte (unused) + LOGIN_KEY_LEN
*/
#define MY_LOGIN_HEADER_LEN (4 + LOGIN_KEY_LEN)
static int read_and_decrypt_file(DYNAMIC_STRING *file_buf)
{
DBUG_ENTER("read_and_decrypt_file");

char cipher[MY_LINE_MAX], plain[MY_LINE_MAX];
uchar len_buf[MAX_CIPHER_STORE_LEN];
int cipher_len= 0, dec_len= 0;

/* Move past key first. */
if (my_seek(g_fd, MY_LOGIN_HEADER_LEN, SEEK_SET, MYF(MY_WME)) //跳过之前的unused bytes和login key部分
!= (MY_LOGIN_HEADER_LEN))
goto error; /* Error while seeking. */

/* First read the length of the cipher. */
while (my_read(g_fd, len_buf, MAX_CIPHER_STORE_LEN, //获取密文的长度
MYF(MY_WME)) == MAX_CIPHER_STORE_LEN)
{
cipher_len= sint4korr(len_buf); //将密文的长度转换成整形

if (cipher_len > MY_LINE_MAX)
goto error;

/* Now read 'cipher_len' bytes from the file. */
if ((int) my_read(g_fd, (uchar *) cipher, cipher_len, MYF(MY_WME)) == cipher_len) //读取相应密文长度的密文
{
if ((dec_len= decrypt_buffer(cipher, cipher_len, plain)) < 0) //解密该密文
goto error;

plain[dec_len]= 0;
dynstr_append(file_buf, plain); //将解密后的密文追加到file_buf中
}
}
verbose_msg("Successfully decrypted the login file.\n");
DBUG_RETURN(0);
error:
my_perror("couldn't decrypt the file");
DBUG_RETURN(-1);
} 

所以该函数的过程,就变为下面四个步骤的重复,只到文件中所有的密文都解密。这样,file_buf中就包含了所有的文件的明文信息:1.获取密文的长度2.根据获取的长度,读取文件中的密文3.根据读取到的密文,进行解密4.将解密后的内容,追加到file_buf缓冲区中。
在函数中,我们看到会将获取到的密文的长度,通过sint4korr转换,那是为什么呢
?从上面我们可以知道,一个cipher其实有一个
4bytes的长度+cipher的字符串所以,通过int4store
将cipher的长度存储在cipher字符串的前4个bytes中,通过sint4korr将cipher前4个bytes中的值转化为实际的cipher长度:

#define int4store(T,A) do { *((char *)(T))=(char) ((A));\
 *(((char *)(T))+1)=(char) (((A) >> 8));\
*(((char *)(T))+2)=(char) (((A) >> 16));\
*(((char *)(T))+3)=(char) (((A) >> 24));\
} while(0)

#define sint4korr(A) (int32) (((int32) ((uchar) (A)[0])) +\
(((int32) ((uchar) (A)[1]) << 8)) +\
(((int32) ((uchar) (A)[2]) << 16)) +\
(((int32) ((int16) (A)[3]) << 24))) 

接下来再看看locate_login_path函数的实现:

  1. static char* locate_login_path(DYNAMIC_STRING *file_buf, const
    char *path_name)
  2. {
  3. DBUG_ENTER(“locate_login_path”);
  4. char *addr= NULL;
  5. DYNAMIC_STRING dy_path_name;
  6. init_dynamic_string(&dy_path_name, “”, 512, 512); //
    初始化dy_path_name动态字符串
  7. //将dy_path_name 设置为[path_name]
  8. dynstr_append(&dy_path_name, “\n[“);
  9. dynstr_append(&dy_path_name, path_name);
  10. dynstr_append(&dy_path_name, “]”);
  11. //检查第一个login-path是否就是要寻找的login-path
  12. /* First check if it is the very first login path. */
  13. if (file_buf->str == strstr(file_buf->str,
    dy_path_name.str + 1))
  14. addr= file_buf->str;
  15. /* If not, scan through the file. */
  16. else
  17. {
  18. addr= strstr(file_buf->str, dy_path_name.str);
  19. if (addr)
  20. addr ++; /* Move past ‘\n’ */
  21. }
  22. dynstr_free(&dy_path_name);
  23. DBUG_RETURN(addr); //返回找到的login-path在file_buf的首地址
  24. }

该函数主要是寻找login-path是否能已经存在,如果已经存在,返回该login-path在file_buf中的首地址。
如果该login-path已经存在,那么我们可能会选择remove该login-path,然后在添加该login-path。

接下来我们看看removelogin-path的实现:

  1. static void remove_login_path(DYNAMIC_STRING *file_buf, const
    char *path_name)
  2. {
  3. DBUG_ENTER(“remove_login_path”);
  4. char *start=NULL, *end= NULL;
  5. int to_move, len, diff;
  6. if((start= locate_login_path(file_buf, path_name)) == NULL)
    //如果该login-path不存在,直接结束
  7. /* login path was not found, skip.. */
  8. goto done;
  9. end= strstr(start, “\n[“);
    //end为从start开始寻找,下一个login-path的起始位置
  10. if (end) //如果该login-path是file_buf中间的某一个login-path
  11. {
  12. end ++; /* Move past ‘\n’ */
  13. len= ((diff= (start – end)) > 0) ? diff : – diff;
  14. to_move= file_buf->length – (end – file_buf->str);
  15. }
  16. else //如果该login-path是该file_buf中最后一个log-path
  17. {
  18. *start= ‘\0’;
  19. file_buf->length= ((diff= (file_buf->str – start)) > 0) ?
    diff : – diff;
  20. goto done;
  21. }
  22. while(to_move —)
    //将该login-path之后的login-path整体前移,覆盖move掉的login-path
  23. *(start ++)= *(end ++);
  24. *start= ‘\0’;
  25. file_buf->length -= len;
  26. done:
  27. DBUG_VOID_RETURN;
  28. }

该函数主要是覆盖已经存在的login-path相关的字符串。
函数:dynstr_append(&file_buf, path_buf.str)
,将新添加的login-path内容,添加到file_buf的末尾。

最后来看看最重要,也是最核心的加密函数encrypt_and_write_file的实现:

static int encrypt_and_write_file(DYNAMIC_STRING *file_buf)
 {
DBUG_ENTER("encrypt_and_write_file");
my_bool done= FALSE;
char cipher[MY_LINE_MAX], *tmp= NULL;
uint bytes_read=0, len= 0;
int enc_len= 0; // Can be negative.

if (reset_login_file(0) == -1) //清空文件,并重新生成随机加密秘钥,并将对称加密秘钥写入文件头部
goto error;
/* Move past key first. */
if (my_seek(g_fd, MY_LOGIN_HEADER_LEN, SEEK_SET, MYF(MY_WME))
!= (MY_LOGIN_HEADER_LEN))
goto error; /* Error while seeking. */

tmp= &file_buf->str[bytes_read];
while(! done)
{
len= 0;

while(*tmp++ != '\n’) //读取file_buf中的每一行内容
if (len < (file_buf->length - bytes_read))
len ++;
else
{
done= TRUE; 
break;
}

if (done)
break;

if ((enc_len= encrypt_buffer(&file_buf->str[bytes_read],++len,cipher+MAX_CIPHER_STORE_LEN))<0) //对读到的这一行内容进行加密,并将密文存放到cipher + MAX_CIPHER_STORE_LEN的地址处goto error;

bytes_read += len;

if (enc_len > MY_LINE_MAX)
goto error;

/* Store cipher length first. */
int4store(cipher, enc_len); //将密文的长度存放到cipher的头部

if ((my_write(g_fd, (const uchar *)cipher, enc_len + MAX_CIPHER_STORE_LEN,
MYF(MY_WME))) != (enc_len + MAX_CIPHER_STORE_LEN)) //将该行加密过的密文写到文件
goto error;
}
verbose_msg("Successfully written encrypted data to the login file.\n");
/* Update file_size */
file_size= bytes_read; //更新文件大小

DBUG_RETURN(0);

error:
my_perror("couldn't encrypt the file");
DBUG_RETURN(-1);
} 

该函数主要功能如下:

  • 读取file_buf中一行
  • 对读取到的行,根据产生的KEY进行加密,将加密后的内容存放到cipher+MAX_CIPHER_STORE_LEN地址处
  • 将密文的长度存放到cipher和cipher+MAX_CIPHER_STORE_LEN之间的地址
  • 将cipher写入文件
  • 更新文件大小

上述1~5一直循环至file_buf中的内容全部加密,并全部写入到文件中为止!
下一节会讲到具体采用的加密算法,并会通过相关的解密算法,编写程序对该文件进行解密操作!!

从mysql5.6开始,mysql推出了加密工具mysql_config_editor。在此之前我们通过将账号和密码明文放入my.cnf,从…

jQuery中ajax的load()与post()方法实例详解,jqueryajax

本文实例讲述了jQuery中ajax的load()与post()方法。分享给大家供大家参考,具体如下:

一、load()方法

在jQuery ajax的load()方法能够载入远程 HTML 文件代码并插入至 DOM
中,这个与post,get还是有一点的区别,但可以快速在页面加载时就加载一个页面的html保存到dom中并且可执行哦。

load()方法默认使用 GET 方式, 如果传递了data参数则使用Post方式.

传递附加参数时自动转换为 POST 方式。jQuery 1.2
中,可以指定选择符,来筛选载入的 HTML 文档,DOM 中将仅插入筛选出的 HTML
代码。语法形如 “url #some > selector”, 默认的选择器是”body>*”.

讲解:

load是最简单的Ajax函数, 但是使用具有局限性:

1.它主要用于直接返回HTML的Ajax接口
2.load是一个jQuery包装集方法,需要在jQuery包装集上调用,并且会将返回的HTML加载到对象中,
即使设置了回调函数也不过不可否认load接口设计巧妙并且使用简单.下面通过示例来演示Load接口的使用:

load()函数:

函数介绍:load(url, [data], [callback]) 返回值:jQuery

参数说明:

url:待装入 HTML 网页网址。
data:(可选参数)发送至服务器的 key/value 数据。
callback:(可选参数)载入成功时回调函数。

下面进行实例演示:

首先建立需要加载的test.html文件:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ajax演示</title>
</head>
<body>
帮客之家(www.jb51.net),提供大量脚本及素材供大家下载!
</body>
</html>

然后建立ajax.html文件,记得引入jquery。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="./jquery-1.7.1.min.js"></script>
<script>
 $(document).ready(function(){
 $("#btn").click(function(){
  $("#result").load("test.html",function(responseText,textStatus){
  $("#display").append("<hr>responseText:"+responseText);
  $("#display").append("<hr>textStatus:"+textStatus);
  }); 
 });
 });
</script>
</head>
<body>
<input type="button" value="测试" id="btn" />
<h2>显示的内容如下:</h2>
<div id="result"></div>
<h2>结果:</h2>
<div id="display"></div>
</body>
</html>

上面的示例演示了如何使用Load方法.

提示:

① 我们要时刻注意浏览器缓存,  当使用GET方式时要添加时间戳参数 (net
Date()).getTime() 来保证每次发送的URL不同, 可以避免浏览器缓存.

② 当在url参数后面添加了一个空格, 比如”  “的时候,
会出现”无法识别符号”的错误, 请求还是能正常发送. 但是无法加载HTML到DOM.
删除后问题解决.

二、post()方法

在jquery中的ajax有二个数据发送模式,一种是get(),前面的文章有讲过,另一种是post()。这里再来给大家介绍一下,有需要了解的朋友可参考.

首先认识要jQuery.post(url, [data], [callback], [type])

对参数进行说明:

url:发送请求地址。
data:待发送 Key/value 参数。
callback:发送成功时回调函数。
type:返回内容格式,xml, html, script, json, text, _default。

说明:

通过远程 HTTP POST 请求载入信息。

这是一个简单的 POST 请求功能以取代复杂 $.ajax
。请求成功时可调用回调函数。如果需要在出错时执行函数,请使用 $.ajax。

先来看一个简单的实例
复制代码 代码如下:<?php echo
json_encode(array(“name”=>$_POST[‘name’]));?>
然后建立ajax.html文件,注意js代码:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="./jquery-1.7.1.min.js"></script>
<script>
 $(document).ready(function(){
 $("#sub").click(function(){
  $.post("testPost.php",{name:$("#name").val()},function(data,textStatus){
  $("#result").append("data:"+data.name);
  $("#result").append("<br>textStatus:"+textStatus);
  },"json");
  return false;
 });
 });
</script>
</head>
<body>
<form action="testPost.php" method="post">
 <input type="text" name="name" id="name" >
 <input type="submit" id="sub" value="提交">
</form>
<h2>显示的内容如下:</h2>
<div id="result"></div>
</body>
</html>

用法2:(点击post数据返回数据)

<input type="button" id="bnajax" value="ajax" onclick="ajaxTest()" />
<script type="text/javascript" >
 function ajaxTest()
 {
 $.post("http://localhost:8012/t.asp", { "txt": "123" },function(data)
 {
  $("#divMsg").html(data);
 }
 );
 }
</script>

例3

JS代码:

<script>
$(document).ready(function(){
  $(".ajax_btn").click(function(){
   $.post("ajax.php",//异步处理动态页面
   {name:$(".name").val()},//获取类名为"name"文本的值,以NAME异步传值
   function(data){//data为反回值,function进行反回值处理
     $(".content").val(data);//获得得反回值后,将其填入到类名为"content"的文本框中
   });
  })
})
</script>

ajax.php代码:

<?php
$name=$_POST["name"];
if($name=="netxu"){
  echo "对不起,".$name."数据存在";
}
else{
  echo "恭喜你,".$name."可以使用";
}
?>

希望本文所述对大家jQuery程序设计有所帮助。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

标签:
网站地图xml地图