在Javascript脚本里,一个cookie 实际就是一个字符串属性。当你读取cookie的值时,就得到一个字符串,里面当前WEB页使用的所有cookies的名称和值。每个cookie除了name名称和value值这两个属性以外,还有四个属性。这些属性是: expires过期时间、 path路径、 domain域、以及 secure安全。
Expires – 过期时间。指定cookie的生命期。具体是值是过期日期。如果想让cookie的存在期限超过当前浏览器会话时间,就必须使用这个属性。当过了到期日期时,浏览器就可以删除cookie文件,没有任何影响。
Path – 路径。指定与cookie关联的WEB页。值可以是一个目录,或者是一个路径。如果http://laifangwen.com/html/java/建立了一个cookie,那么在http://laifangwen.com/html/java/目录里的所有页面,以及该目录下面任何子目录里的页面都可以访问这个cookie。这就是说,在http://laifangwen.com/html/java/stories/articles 里的任何页面都可以访问http://laifangwen.com/html/java/index.html建立的cookie。但是,如果http://laifangwen.com/html/asp/ 需要访问http://laifangwen.com/html/java/index.html设置的cookes,该怎么办?这时,我们要把cookies 的path属性设置成“/”。在指定路径的时候,凡是来自同一服务器,URL里有相同路径的所有WEB页面都可以共享cookies。现在看另一个例子:如果想让 http://laifangwen.com/devhead/filters/ 和http://laifangwen.com/devhead/stories/共享cookies,就要把path设成“/devhead”。
Domain – 域。指定关联的WEB服务器或域。值是域名,比如laifangwen.com。这是对path路径属性的一个延伸。如果我们想让 blog.laifangen.com 能够访问www.laifangwen.com设置的cookies,该怎么办? 我们可以把domain属性设置成“laifangwen.com”,并把path属性设置成“/”。FYI:不能把cookies域属性设置成与设置它的服务器的所在域不同的值。
Secure – 安全。指定cookie的值通过网络如何在用户和WEB服务器之间传递。这个属性的值或者是“secure”,或者为空。缺省情况下,该属性为空,也就是使用不安全的HTTP连接传递数据。如果一个 cookie 标记为secure,那么,它与WEB服务器之间就通过HTTPS或者其它安全协议传递数据。不过,设置了secure属性不代表其他人不能看到你机器本地保存的cookie。换句话说,把cookie设置为secure,只保证cookie与WEB服务器之间的数据传输过程加密,而保存在本地的cookie文件并不加密。如果想让本地cookie也加密,得自己加密数据。
操纵Cookies
请记住,cookie就是文档的一个字符串属性。要保存cookie,只要建立一个字符串,格式是name=<value>(名称=值),然后把文档的 document.cookie 设置成与它相等即可。比如,假设想保存表单接收到的用户名,那么代码看起来就象这样:
document.cookie = "username" + escape(form.username.value);
在这里,使用 escape() 函数非常重要,因为cookie值里可能包含分号、逗号或者空格。这就是说,在读取cookie值时,必须使用对应的unescape()函数给值解码。
我们当然还得介绍cookie的四个属性。这些属性用下面的格式加到字符串值后面:
name=<value>[; expires=<date>][; domain=<domain>][; path=<path>][; secure]
名称=<值>[; expires=<日期>][; domain=<域>][; path=<路径>][; 安全]
<value>, <date>, <domain> 和 <path> 应当用对应的值替换。<date> 应当使用GMT格式,可以使用Javascript脚本语言的日期类Date的.toGMTString() 方法得到这一GMT格式的日期值。方括号代表这项是可选的。比如在 [; secure]两边的方括号代表要想把cookie设置成安全的,就需要把"; secure" 加到cookie字符串值的后面。如果"; secure" 没有加到cookie字符串后面,那么这个cookie就是不安全的。不要把尖括号<> 和方括号[] 加到cookie里(除非它们是某些值的内容)。设置属性时,不限属性,可以用任何顺序设置。
下面是一个例子,在这个例子里,cookie "username" 被设置成在15分钟之后过期,可以被服务器上的所有目录访问,可以被"mydomain.com"域里的所有服务器访问,安全状态为安全。
// Date() 的构造器设置以毫秒为单位
// .getTime() 方法返回时间,单位为毫秒
// 所以要设置15分钟到期,要用60000毫秒乘15分钟
var expiration = new Date((new Date()).getTime() + 15 * 60000);
document.cookie = "username=" + escape(form.username.value)+ "; expires ="
+ expiration.toGMTString() + "; path=" + "/" + "; _
domain=" + "mydomain.com" + "; secure";
读取cookies值有点象个小把戏,因为你一次就得到了属于当前文档的所有cookies。
// 下面这个语句读取了属于当前文档的所有cookies
var allcookies = document.cookie;
现在,我们得解析allcookies变量里的不同cookies,找到感兴趣的指定cookie。这个工作很简单,因为我们可以利用Javascript语言提供的扩展字符串支持。
如果我们对前面分配的cookie "username" 感兴趣,可以用下面的脚本来读取它的值。
// 我们定义一个函数,用来读取特定的cookie值。
function getCookie(cookie_name)
{
var allcookies = document.cookie;
var cookie_pos = allcookies.indexOf(cookie_name);
// 如果找到了索引,就代表cookie存在,
// 反之,就说明不存在。
if (cookie_pos != -1)
{
// 把cookie_pos放在值的开始,只要给值加1即可。
cookie_pos += cookie_name.length + 1;
var cookie_end = allcookies.indexOf(";", cookie_pos);
if (cookie_end == -1)
{
cookie_end = allcookies.length;
}
var value = unescape(allcookies.substring(cookie_pos, cookie_end));
}
return value;
}
// 调用函数
var cookie_val = getCookie("username");
上面例程里的 cookie_val 变量可以用来生成动态内容,或者发送给服务器端CGI脚本进行处理。现在你知道了使用Javascript脚本操纵cookies的基本方法。但是,如果你跟我一样,那么我们要做的第一件事,就是建立一些接口函数,把cookies处理上的麻烦隐藏起来。不过,在你开始编程之前,稍候片刻。这些工作,早就有人替你做好了。你要做的,只是到哪去找这些接口函数而已。
比如,在David Flangan的Javascript: The Definitive Guide 3rd Ed.这本书里,可以找到很好的cookie应用类。你也可以在Oreilly的WEB站点上找到这本书里的例子。本文最后的链接列表里,有一些访问这些cookie示例的直接链接。
/**
* 查询指定名称的Cookie值
* @note 需要注意有可能出现同名cookie的问题
* @param {Object} key
* @param {Object} 设置当读取不到key时返回的默认值
* @return {String} 返回读取到的Cookie的值,
* 如果读取不到相应的Cookie,则判断defValue是否有效,有效则返回defValue,否则返回null
*/
function getCookie(key,defValue){
var cookie,value;
if(!key){
return null;
}
cookie = document.cookie;
// 所有cookie的key都小写化处理
key = key.toLowerCase();
value = find(cookie,key+"=",";",null,false,null);
return value === null ? defValue : unescape(value);
}
/**
* 设置cookie
* @param {String} key
* @param {String} value
* @param {Number} expires 单位为秒
* @param {String} path 路径
* @param {String} domain 主机
* @param {Boolean} secure 安全级别
*/
function setCookie(key, value, expires, path,domain,secure){
// key无效则不做任何操作
if(!key){
return;
}
// 所有cookie的key都小写化处理
key = key.toLowerCase();
key = key + '=' + escape(value) + ";";
expires = expires ? ("expires=" + new Date(new Date().getTime() + expires * 1000).toGMTString()) + ";" : "";
path = !!path ? "path=" + path + ";" : "path=/;";
domain = domain ? ("domain=" + domain) + ";" : "";
secure = secure ? "secure=true;" : "";
document.cookie =[key,expires,path,domain,secure].join("");
}
/**
* 删除指定Cookie
* @param {Object} key
* @param {Object} path
* @param {Object} domain
*/
function delCookie(key,path,domain){
// 超时设置为过去的时间,cookie会立即失效
key = key.toLowerCase();
setCookie(key,"",-1000,path,domain);
}
/**
* 从字符串中获取夹在指定前缀和后缀之间的值
* @example
* userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.0.2) Gecko/2008082714 Firefox/3.0.2"
*
* prefix="windows nt"
* suffix=";"
* find(userAgent,prefix,suffix) returns " 5.2";
* @param {Object} str 源字符串
* @param {Object} prefix 前缀
* @param {Object} suffix 结束符,若不指定,则匹配到字符串结尾;如果指定了,但是匹配不到,则同样匹配到字符串结尾。
* @param {Boolean} matchFirstOnly 是否找到第一个匹配项,设置为false则查找最后一个匹配项,默认为false
* @param {Boolean} ignoreCase 忽略大小写来查找,默认值为true
* @param {Boolean} trimBlank 是否删除值首尾的空白符,默认值为true
* @return {String} 查找到的字符串,若找不到则返回null
*/
function find(str,prefix,suffix,matchFirstOnly,ignoreCase,trimBlank){
var start,end,middle,value=null;
matchFirstOnly = (matchFirstOnly === true);
ignoreCase = (ignoreCase !== false);
trimBlank = (trimBlank !== false);
// 如果忽略默认值
if(ignoreCase){
str = str.toLowerCase();
prefix = prefix.toLowerCase();
suffix = suffix && suffix.toLowerCase();
}
if(matchFirstOnly){
start = str.indexOf(prefix);
}else{
start = str.lastIndexOf(prefix);
}
if (start > -1) {
// 如果没有指定后缀,则直接匹配到字符串结尾
middle = start + prefix.length;
if (!suffix) {
value = str.substring(middle);
}
else {
end = str.indexOf(suffix, middle);
if (end > -1) {
value = str.substring(middle, end);
}
else {
value = str.substring(middle);
}
}
if(trimBlank){
value = value.replace(/^/s*(.*?)/s*$/, '$1');
}
}
return value;
}