JavaScript-Cookie
Cookie
之前在php里草草用过cookie,后来测试xss也在JS里使用过诸如“document.cookie”,但一直未全面的了解JS中如何设置、获取和删除cookie。
刚刚看JS的cookie部分内容时想当然的写了个alert(document.cookie["username"]);,结果返回了Undifined,显然瞎YY是不对的。补一下这块的知识缺口并记录。
创建Cookie
语法:document.cookie="cookieName=Attr; expires=Time;path=PATH";
cookieName为cookie的名字,expires为过期时间,path为作用域。
- eg: document.cookie="username=Alice; expires=Thu, 18 Dec 2019 12:00:00 GMT; path="/";
expire-time和path非必须,属于可选项。
expires 是cookie的有效时间,写起来太麻烦,直接用Date()对象比较方便。
cookie是有作用域的,默认是当前页面所在的目录及其子目录;path="/" 意思是根目录下均有效,即整个项目都可用。
读取 Cookie
- var x = document.cookie;
注意,返回的是所有的cookie组成的字符串,每个cookie由";"分隔
document.cookie="userID=1";
document.cookie="username=Alice";
document.cookie = "password=root";
//获取cookie字符串
var strCookie=document.cookie;
//如我们所知,document.cookie返回的是所有的cookie组成的字符串,打印出来看看
document.write("document.cookie获得的内容是:" + strCookie+"<br>");
//查看它用什么类型返回的,经验证,用字符串返回的
document.write("document.cookie获得的内容的类型是:"+ typeof strCookie+"<br>");
运行结果如图:
那么如何get到想要的某条cookie而不是所有呢?
Method1
考虑到document.cookie返回的是字符串,对返回的String进行处理,找到所需的片段并将其“裁剪”出即可。
function getCookieString(cookieName)
{
var strCookie = document.cookie;
//start为cookie起始下标,不存在则start=-1;
var start = strCookie.indexOf(cookieName);
if (start < 0){
return null;
}
//从起始处往后的第一个";"为该cookie的结束,记下结束下标
var end = strCookie.indexOf(";", start);
//start往后cookieName.length + 1(=号)为cookie值的开始下标
start += cookieName.length+1;
//cookie值的长度为结束下标-起始下标,即end-start
var len = end - start;
var cookie = strCookie.substr(start, len);
return cookie;
}
//应打印出Alice
document.write("查找cookie中username项的值: username = " + getCookieByStringMethod("username")+ "<br>");
//没有name为users的cookie
document.write("查找cookie中users项的值: users = " + getCookieByStringMethod("users"));
运行结果如图:
Method2
潇洒的正则表达式匹配法
其实主要要记的就是这个了,看W3C很潇洒的给了这个方法,为了理解这个方法,花了点功夫去看正则表达式。
function getCookieByReg(name)
{
var arr;
var reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
if(arr=document.cookie.match(reg))
return (arr[2]);
else
return null;
}
难点就在理解这个匹配式 "(^| )"+name+"=([^;]*)(;|$)" ;虽然用起来没问题,但没找到相应解释,只好自己想办法理解了。
我的理解是:
在字符串中匹配以“name”开头的;name后跟着的是"=";“=”后是0个或多个非“;”的内容(因为“;”代表结束结束);结尾处,也即是匹配串最后的字符是“;”,或者就直接没有“;”的结尾(也可以说是非“;”的任意字符来结尾)的字串,这样匹配出来的就是cookie的某个属性。
match()方法执行后获得的结果是一个长为4的数组arr,arr[0]包含了所有匹配内容,后续下标1-n为各个匹配内容。这里有3个匹配项,因此数组长度为1+3=4。
我们希望获取的cookie项的值是第2个匹配项里的内容,它的数组下标为2。arr[1]是空,arr[3]是“;”或者空(可以以“;”结尾,也可以什么都没有的结尾)。
代码:
结果:
另:
匹配式末尾的 (;|$) 是有存在意义的,因为非最后一项的cookie项是以“;”结尾的,而最后一项的cookie后面是没有“;”的。
注意,这里有个很小的截图
如上图所示,如果取最后项的cookie,那个名为Weblogin的cookie,少了这个 “$”符做结束的判断就无法完成匹配,进而取出本存在的值。
参照:
注意,这里有个很小的截图
正常:
注意,这里有个很小的截图