在网站中,我们经常看到每当我们准备登陆时,网页询问我们是否保存用户名和密码,以便下次登陆时不用再次输入。诸如此类的功能如何实现哪?经过两天的研究,终于有了收获!现将我的经验与大家分享。
在网页中记录用户的信息通常有如下几种方式:Session、Cookie、以及.Net环境下的ViewState等。比较起来,Session将用户的信息暂存在内存中,除非用户关闭网页,否则信息将一直有效。所以,用Session保存的信息很容易丢失。Cookie用来将用户的信息保存到用户机的文件中,这样信息就可以长久的保存。前两种都是传统的保存方式,而ViewState是在微软.Net环境下新推出的一种对象,它其实是一种特殊的Session,不过一般将信息保存在客户端。关于ViewState的用法大家可以参考一些资料,我在《谨慎Asp.net中static变量的用法》一文中也有叙述。
下面我将以用户名和密码为例介绍如何通过Cookie保存用户的信息。
因为Cookie是通过计算机上的文件来记录有关信息,所以涉及到对Cookie的操作无外乎读取、赋值和删除。另外,由于Cookie提供了一项有效期的功能,所以还可以对Cookie设置有效期。下面将在DHTML和VS.Net两种环境下分别介绍如何实现Cookie的各种操作。
一、DHTML环境
这种环境下我们使用的是传统的JavaScript脚本,通过对页面中各种对象的属性和事件进行操作来完成我们的预期任务。
1、读取Cookie值
Cookie值是按照索引存储的,也就是说不同的索引有不同的Cookie值。所以我们就可以将我们想要存储的对象(在这里为用户名)作为索引,读取该存储对象的Cookie值。方法如下:
- function GetCookie (name)
- {
- var arg = name + "=";
- var alen = arg.length;
- var clen = window.document.cookie.length;
- var i = 0;
- while (i < clen)
- {
- var j = i + alen;
- if (window.document.cookie.substring(i, j) == arg) return getCookieVal (j);
- i = window.document.cookie.indexOf(" ", i) + 1;
- if (i == 0)
- break;
- }
- return null;
- }
- function getCookieVal (offset)
- {
- var endstr = window.document.cookie.indexOf (";", offset);
- if (endstr == -1)
- endstr = window.document.cookie.length;
- return unescape(window.document.cookie.substring(offset, endstr));
- }
为什么读取Cookie值还要两个函数来完成?这是因为Cookie值是按照“Cookie名;”+“Cookie值;”+“有效期;”+“路径”的格式来存储的。这将在下文中提到。这样初次读到的Cookie是一连串的以分号分隔的字符串。我们还需要对其进行进一步处理才能提取出我们想要的信息。在上面两个函数中,第一个函数GetCookie用来按索引获取我们想要读取的Cookie的位置,第二个函数getCookieVal用来提取Cookie中我们想要的信息。所以使用时直接调用GetCookie(name)就可以了,其中name是Cookie的索引,也就是名称,或者直接点说就是我们要存储其值的东西。
2、设置Cookie值
正如上面所说,Cookie的存取方式有点类似于哈希表,是以名称作为索引存取的。一个Cookie的格式如下:
Cookie名称(作为Cookie的索引便于以后的各种操作)+“=”+Cookie值+“;expires=+有效期+“;path=”+路径+“;domain=”+域+“;secure=”+安全级别
可以看出每个Cookie实际有6个属性,这些属性恰好构成了一条记录。多条Cookie记录在硬盘中是以集合的方式存取的。也就是说所有Cookie记录构成了类似于一张表的结构。而Cookie又可以有多个集,那时不是就可以理解成一个库哪?这里不去讲解怎么样以表或库的方式读写Cookie记录集,只是讲解基本的Cookie操作。并且我还没有发现真正有把Cookie集合当成表一样的专门操作方法。毕竟,以表的方式理解Cookie集合只是我的一家之言,仅供大家理解上的方便。
正因为每个Cookie实际上是有多个属性组成的,所以设置Cookie时理所当然地应该设置多个属性值,虽然不是每一个属性都必须填写,但大家至少应该把Cookie名称和Cookie值填上,否则这个Cookie就没有任何意义了。设置一个Cookie值的方法如下:
- function SetCookie (name, value)
- {
- var exp = new Date();
- exp.setTime(exp.getTime() + (30*24*60*60*1000));
- window.document.cookie = name + "=" + escape (value) + "; expires=" + exp.toGMTString()+";path=/";
- }
其中,name为Cookie的名称,value为Cookie的值。如果还想指定Cookie的有效期,再传入一个时间参数就可以了,不过要注意这里的时间是以毫秒计算的,所以如果要设置日月年等长时间时要进行计算。需要注意的是如果Cookie的名称和值中含有汉字的话,最好事先对其进行编码,否则可能显示结果不会很理想。
3、删除Cookie
这么叫也许并不恰当,因为以下的介绍忠并没有真正的删除Cookie。我们就勉强这么叫吧。上面说每一个Cookie都有一个有效期,过了这个有效期该Cookie就会失效,获取到的Cookie值将为空(null),使用该Cookie的值将会出错。所以如果要删除某个Cookie的话,只要让其过期就可以了。所以删除Cookie的操作就是让其过期的操作:
- function DeleteCookie (name)
- {
- var exp = new Date();
- exp.setTime (exp.getTime() - 100);
- var cval = GetCookie (name);
- window.document.cookie = name + "=" + cval + "; expires=" + exp.toGMTString()+";path=/";
- }
有上述代码也可以看出,删除操作其实就是让某个Cookie的有效期设置为当前时间减去1毫秒,当然会过期了!
那么如何将上述代码应用到DHTML的开发过程中哪?下面就以记录用户名和密码到Cookie中为例进行讲解。
为了简单起见,我们只在页面中放置一个用户名文本域、一个密码域、一个按钮和一个复选框。页面的布局代码如下:
- <html>
- <head>
- <title>记录用户名和密码到Cookie中</title>
- </head>
- <body>
- 请输入用户名:<input type="text" id = "username" ><br/>
- 请输入密码:<input type="password" id="password"> <input type="checkbox" name = "remember" id="remember"></input>记住密码<br/>
- <input value="记录" type="button" onClick="remember()"> <input value="删除" type="button" onClick="DelCookie()">
- <input type="button" value="显示cookie" onClick="showpassword()">
- </body>
- </html>
下面就开始完成功能代码的编写。本来用户单击“确定”按钮后要对用户名和密码进行验证,并且进入相关页面,我们在这里换成记录用户名和密码的功能。
将上述三个Cookie的函数粘贴到html代码的<head>和</head>之间(不要放在<title>和</title>之间),然后在<input value="记录" type="button">中添加一个单击事件处理程序:<input value="记录" type="button" onClick="remember()">。在<head>和</head>之间实现remember()函数:
- function remember()
- {
- if(document.getElementById("remember").checked){
- SetCookie(document.getElementById("username").value,document.getElementById("password").value);
- alert("Saved!");
- }
- }
这样就可以在用户单击了“记录”按钮后将用户名和对应的密码记录到Cookie中。
那么如何在用户输入用户名后自动填入对应的密码哪?这就要在<input id="username" type="text">中添加一个事件处理函数:<input id="username" type="text" οnblur="showpassword()">。然后把showpassword()的定义同样放到<head>和</head>之间:
- function showpassword()
- {
- return GetCookie(document.getElementById("username").value);
- }
以上就完成了对特定用户密码的记录。下面我们完成密码的删除部分。在<input value="删除" type="button">中添加一个事件处理函数:<input value="删除" type="button" onClick="DelCookie()">。然后在<head>和</head>之间实现DelCookie()函数:
- function DelCookie()
- {
- DeleteCookie(document.getElementById("username").value);
- }
现在大家可以试验一下,看看预期的功能可否实现。如果大家试验过后就会发现,当我们删除掉某个用户的密码后,每次焦点从username中移出时,password中总是显示四个掩码,而不是空,这是为什么哪?如果大家用alert()语句把文本框中的内容输出的话,就会发现那四个掩码其实是“null”这个单词。这就表明其实已经删除了,但我们显示密码时没有排除这种情况。所以在showpassword()函数中应进行判断,非空后再把结果赋给password域:
- function showpassword()
- {
- var p=GetCookie(document.getElementById("username").value);
- if(p!=null)
- document.getElementById("password").value= p;
- }
好了,大功告成。完整的代码如下所示:
- <html>
- <head>
- <title>记录用户名和密码到Cookie中</title>
- </head>
- <body>
- 请输入用户名:<input type="text" id = "username" οnblur="showpassword()"><br/>
- 请输入密码:<input type="password" id="password"> <input type="checkbox" name = "remember" id="remember"></input>记住密码<br/>
- <input value="记录" type="button" onClick="remember()"> <input value="删除" type="button" onClick="DelCookie()">
- <script type="text/javascript">
- function GetCookie (name)
- {
- var arg = name + "=";
- var alen = arg.length;
- var clen = window.document.cookie.length;
- var i = 0;
- while (i < clen)
- {
- var j = i + alen;
- if (window.document.cookie.substring(i, j) == arg) return getCookieVal (j);
- i = window.document.cookie.indexOf(" ", i) + 1;
- if (i == 0)
- break;
- }
- return null;
- }
- function getCookieVal (offset)
- {
- var endstr = window.document.cookie.indexOf (";", offset);
- if (endstr == -1)
- endstr = window.document.cookie.length;
- return unescape(window.document.cookie.substring(offset, endstr));
- }
- function SetCookie (name, value)
- {
- var exp = new Date();
- exp.setTime(exp.getTime() + (30*24*60*60*1000));
- window.document.cookie = name + "=" + escape (value) + "; expires=" + exp.toGMTString()+";path=/";
- }
- function DeleteCookie (name)
- {
- var exp = new Date();
- exp.setTime (exp.getTime() - 100);
- var cval = GetCookie (name);
- window.document.cookie = name + "=" + cval + "; expires=" + exp.toGMTString()+";path=/";
- }
- function DelCookie()
- {
- DeleteCookie(document.getElementById("username").value);
- }
- function remember()
- {
- if(document.getElementById("remember").checked){
- SetCookie(document.getElementById("username").value,document.getElementById("password").value);
- alert("Saved!");
- }
- }
- function showpassword()
- {
- var p=GetCookie(document.getElementById("username").value);
- if(p!=null)
- document.getElementById("password").value= p;
- }
- </script>
- </body>
- </html>
下面是一个php端使用cookie做的一个简单页面计数器
-
- <?php
- session_start();
- if(!isset($_COOKIE['kookie']))
- {
- $pagecount = 0;
- setcookie("kookie",$pagecount);
- echo "<center>This is the firest time you hvae accessed this page in this session.</center>";
- echo "<center> A cookie was sent to you and stored in your computer.</center>";
- }else {
- $pagecount = ++$_COOKIE['kookie'];
- setcookie("kookie",$pagecount,time()-10);
- setcookie("kookie",$pagecount);
- echo "<center>View Count :<b> ".$_COOKIE['kookie']."</b><center>\n<br>";
- }
- ?>
- <html>
- <head>
- <title>Page title</title>
- </head>
- <body>
- <center><b>Refresh button will refresh the page and the page count! :-)
- <b></center>
- </body>
- </html>