在网站中,我们经常看到每当我们准备登陆时,网页询问我们是否保存用户名和密码,以便下次登陆时不用再次输入。诸如此类的功能如何实现哪?经过两天的研究,终于有了收获!现将我的经验与大家分享。
在网页中记录用户的信息通常有如下几种方式: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() - 1);
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"><br>
请输入密码:<input type="password"> <input type="checkbox">记住用户名和密码<br>
<input value="记录" type="button"> <input value="删除" type="button">
</body>
</html>
下面就开始完成功能代码的编写。本来用户单击“确定”按钮后要对用户名和密码进行验证,并且进入相关页面,我们在这里换成记录用户名和密码的功能。
将上述三个Cookie的函数粘贴到html代码的<head>和</head>之间(不要放在<title> 和</title>之间),然后在<input value="记录" type="button">中添加一个单击事件处理程序:<input value="记录" type="button" >。在<head>和</head>之间实现remember()函数:
function remember()
{
if(document.all.remem.checked)
SetCookie(document.all.username.value,document.all.password.value);
}
这样就可以在用户单击了“记录”按钮后将用户名和对应的密码记录到Cookie中。
那么如何在用户输入用户名后自动填入对应的密码哪?这就要在<input type="text">中添加一个事件处理函数:<input type="text" >。然后把showpassword()的定义同样放到<head>和</head>之间:
function showpassword()
{
return GetCookie(document.all.username.value);
}
以上就完成了对特定用户密码的记录。下面我们完成密码的删除部分。在<input value="删除" type="button">中添加一个事件处理函数:<input value="删除" type="button" >。然后在<head>和</head>之间实现DelCookie()函数:
function DelCookie()
{
DeleteCookie(document.all.username.value);
}
现在大家可以试验一下,看看预期的功能可否实现。如果大家试验过后就会发现,当我们删除掉某个用户的密码后,每次焦点从username中移出 时,password中总是显示四个掩码,而不是空,这是为什么哪?如果大家用alert()语句把文本框中的内容输出的话,就会发现那四个掩码其实是 “null”这个单词。这就表明其实已经删除了,但我们显示密码时没有排除这种情况。所以在showpassword()函数中应进行判断,非空后再把结 果赋给password域:
function showpassword()
{
var p=GetCookie(document.all.username.value);
if(p!=null)
document.all.password.value= p;
}
好了,大功告成。完整的代码如下所示:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>记录用户名和密码到Cookie中</title>
<script>
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.all.username.value);
}
function remember()
{
if(document.all.remember.checked)
SetCookie(document.all.username.value,document.all.password.value);
}
function showpassword()
{
var p=GetCookie(document.all.username.value);
if(p!=null)
document.all.password.value= p;
}
</script>
</head>
<body>
请输入用户名:<input type="text" ><br>
请输入密码:<input type="password"> <input type="checkbox">记住密码
<br>
<input value="记录" type="button" > <input value="删除" type="button"
onClick="DelCookie()">
</body>
</html>
二、.Net环境
.Net以其强大的功能而著称。所以在.Net中提供了许多针对Cookie的类,可以很方便地完成对Cookie的各类操作。在.Net中有一个类 HttpCookie,这个类中保存了Cookie的全部信息,包括Cookie名称、Cookie值、有效期等。我们在使用时先新建一个 HttpCookie的对象,然后用Response.Cookies下的方法来操作这个对象就可以了。
声明一个HttpCookie对象的方法为:HttpCookie cookiename = new HttpCookie(Cookie的名称, Cookie的值);其中,cookiename是对象名。然后,我们就可以为cookiename的各个属性赋值。
当向系统中添加该Cookie时只要用Response.AppendCookie(cookiename);就可以了,或者用 Response.Cookies.Add(cookiename);。读取Cookie时用Response.Cookies.Get(Cookie名 称);删除Cookie时用Response.Cookies.Remove(Cookie名称);,但我试了一下,删不掉。所以还是用以前的思路,把该 Cookie的有效期设置为过时就可以了,方法如下:
HttpCookie ckUserInfo = Request.Cookies[txtUserName.Text.Trim()];
ckUserInfo.Expires = DateTime.Today.AddDays(-1);
Response.Cookies.Set(ckUserInfo);
以上操作就可以完成Cookie的基本操作。因为我还想实现当用户输完用户名后把焦点从用户名框转移到密码框时自动在密码框中输出该用户对应的密码,所以 还得增加一个javascript处理函数showpassword()。这个函数完全和上面DHTML中的showpassword()一样。所以, 在.Net中完全可以使用以前DHTML中的方法。我们只要在页面导入时为用户名框添加一个onblur属性即可。Login.aspx的代码如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="login.aspx.cs" Inherits="login" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>无标题页</title>
</head>
<script>
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 showpassword()
{
var p=GetCookie(document.all.txtUserName.value);
if(p!=null)
document.all.txtPassword.value= p;
}
</script>
<body>
<form runat="server">
<div>
请输入用户名:<asp:TextBox runat="server"></asp:TextBox><br />
请输入密码: <asp:TextBox runat="server" TextMode="Password"
Width="149px"></asp:TextBox> <asp:CheckBox runat="server" Text="记住用户名和密码" /><br />
<asp:Button runat="server"
Text="记录" />
<asp:Button runat="server" Text="删除" />
</div>
</form>
</body>
</html>
Login.aspx.cs的代码如下:
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
{
protected void Page_Load(object sender, EventArgs e)
{
txtUserName.Attributes.Add("onblur", "showpassword()");
}
protected void btnRem_Click(object sender, EventArgs e)
{
if (chkRem.Checked)
{
HttpCookie ckUserInfo = new HttpCookie(txtUserName.Text.Trim(), txtPassword.Text);
ckUserInfo.Expires = DateTime.Now.AddYears(1);
Response.AppendCookie(ckUserInfo);
}
}
protected void btnDel_Click(object sender, EventArgs e)
{
HttpCookie ckUserInfo = Request.Cookies[txtUserName.Text.Trim()];
ckUserInfo.Expires = DateTime.Today.AddDays(-1);
Response.Cookies.Set(ckUserInfo);
}
}
好了,大功全部告成。如果大家还想进行更高级的操作的话,可以用这些基本功能进行开发,思路都是一样的。有什么更好的思路可以提出来,我们共同交流。