假设
基于这个问题,我认为这个功能的一些假设/要求包括:
It will be used as a library function, and so meant to be dropped into any codebase;
As such, it will need to work in many different environments, i.e. work with legacy JS code, CMSes of various levels of quality, etc.;
To inter-operate with code written by other people and/or code that you do not control, the function should not make any assumptions on how cookie names or values are encoded. Calling the function with a string "foo:bar[0]" should return a cookie (literally) named "foo:bar[0]";
New cookies may be written and/or existing cookies modified at any point during lifetime of the page.
在这些假设下,很明显encodeURIComponent / decodeURIComponent不应该被使用;这样做假设设置cookie的代码也使用这些函数对其进行编码。
如果cookie名称可以包含特殊字符,则正则表达式方法就会出现问题。jQuery。Cookie在存储Cookie时对Cookie名称(实际上是名称和值)进行编码,在检索Cookie时对名称进行解码,从而解决了这个问题。正则表达式的解决方案如下。
除非您只读取您完全控制的cookie,否则从文档中读取cookie也是可取的。直接Cookie,而不是缓存结果,因为没有办法知道如果缓存是无效的而不读取文档。饼干了。
(当访问和解析文档时。cookie会比使用缓存稍微慢一点,它不会像读取DOM的其他部分那么慢,因为cookie在DOM /渲染树中不发挥作用。)
循环函数
下面是Code Golf的答案,基于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或undefined,也就是说,如果有一个名为“null”的cookie, readCookie(null)将返回其值。如果需要处理这种情况,请相应地调整代码。