假设条件
基于这个问题,我认为此功能的一些假设/要求包括:
- 它将用作库函数,因此意在放入任何代码库中。
- 因此,它将需要在许多不同的环境中工作,例如,使用旧版JS代码,各种质量级别的CMS等。
- 为了与其他人编写的代码和/或不受您控制的代码进行互操作,该函数不应假设如何对cookie名称或值进行编码。用字符串调用该函数
"foo:bar[0]"
应返回一个名为“ foo:bar [0]”的cookie(从字面上看)。
- 在页面生命周期的任何时候都可以编写新的cookie和/或修改现有的cookie。
在这些假设下,很明显encodeURIComponent
/ decodeURIComponent
不应该使用;这样做是假设设置cookie的代码也使用这些功能对其进行了编码。
如果cookie名称可以包含特殊字符,则正则表达式方法会出现问题。jQuery.cookie通过在存储cookie时对cookie名称(实际上是名称和值)进行编码,并在检索cookie时对该名称进行解码来解决此问题。正则表达式解决方案如下。
除非您只读取完全控制的cookie,否则建议直接读取cookiedocument.cookie
而不缓存结果,因为如果不document.cookie
重新读取就无法知道缓存是否无效。
(虽然访问和解析document.cookies
将比使用缓存慢一些,但它不会像读取DOM的其他部分那样慢,因为cookie在DOM /渲染树中不起作用。)
基于循环的功能
这是基于PPK(基于循环)功能的Code Golf答案:
function readCookie(name) {
name += '=';
for (var ca = document.cookie.split(/;\s*/), i = ca.length - 1; i >= 0; i--)
if (!ca[i].indexOf(name))
return ca[i].replace(name, '');
}
缩小后为128个字符(不包括函数名称):
function readCookie(n){n+='=';for(var a=document.cookie.split(/;\s*/),i=a.length-1;i>=0;i--)if(!a[i].indexOf(n))return a[i].replace(n,'');}
基于正则表达式的功能
更新:如果您真的想要一个正则表达式解决方案:
function readCookie(name) {
return (name = new RegExp('(?:^|;\\s*)' + ('' + name).replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') + '=([^;]*)').exec(document.cookie)) && name[1];
}
在构造RegExp对象之前,这会转义 cookie名称中的所有特殊字符。精简版,总共134个字符(不包括函数名称):
function readCookie(n){return(n=new RegExp('(?:^|;\\s*)'+(''+n).replace(/[-[\]{}()*+?.,\\^$|#\s]/g,'\\$&')+'=([^;]*)').exec(document.cookie))&&n[1];}
正如Rudu和cwolves在评论中指出的那样,可以将正则表达式转义正则表达式缩短几个字符。我认为最好保持转义的正则表达式一致(您可能在其他地方使用它),但是他们的建议值得考虑。
笔记
这两个函数都不会处理null
或undefined
,即,如果有一个名为“ null”的cookie,readCookie(null)
将返回其值。如果需要处理这种情况,请相应地修改代码。