假设
基于这个问题,我相信这个功能的一些假设/要求包括:
- 它将用作库函数,因此意味着可以放入任何代码库中;
- 因此,它需要在许多不同的环境中工作,即使用遗留 JS 代码、各种质量级别的 CMS 等;
- 为了与其他人编写的代码和/或您无法控制的代码进行互操作,该函数不应对 cookie 名称或值的编码方式做出任何假设。用字符串调用函数
"foo:bar[0]"
应该返回一个名为“foo:bar[0]”的cookie(字面意思);
- 在页面生命周期内的任何时候,都可以写入新的 cookie和/或修改现有的 cookie。
在这些假设下,很明显不应该使用encodeURIComponent
/ ;这样做假设设置 cookie 的代码也使用这些函数对其进行编码。decodeURIComponent
如果 cookie 名称可以包含特殊字符,正则表达式方法就会出现问题。jQuery.cookie 通过在存储 cookie 时对 cookie 名称(实际上是名称和值)进行编码,并在检索 cookie 时对名称进行解码来解决这个问题。正则表达式解决方案如下。
除非您只读取您完全控制的 cookie,否则建议直接从中读取 cookiedocument.cookie
而不要缓存结果,因为如果不document.cookie
再次读取就无法知道缓存是否无效。
(虽然访问和解析document.cookies
会比使用缓存稍慢,但它不会像读取 DOM 的其他部分一样慢,因为 cookie 在 DOM/渲染树中不起作用。)
基于循环的函数
这是代码高尔夫的答案,基于 PPK 的(基于循环的)函数:
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
or undefined
,即如果存在名为“null”的 cookie,readCookie(null)
将返回其值。如果您需要处理这种情况,请相应地调整代码。