Yah*_*hel 180 javascript cookies
在JavaScript中读取cookie的最短,准确和跨浏览器兼容的方法是什么?
通常,在构建独立脚本(我不能拥有任何外部依赖项)时,我发现自己添加了一个用于读取cookie的函数,并且通常会回退到QuirksMode.orgreadCookie()方法(280字节,216缩小).
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
它完成了这项工作,但它的丑陋,每次都增加了相当多的膨胀.
jQuery.cookie使用这样的方法(修改,165字节,125缩小):
function read_cookie(key)
{
var result;
return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? (result[1]) : null;
}
Run Code Online (Sandbox Code Playgroud)
请注意,这不是"Code Golf"竞赛:我有理由减少readCookie功能的大小,并确保我的解决方案有效.
Mar*_*ahn 181
这将只会遇到document.cookie一次.每个后续请求都是即时的.
(function(){
var cookies;
function readCookie(name,c,C,i){
if(cookies){ return cookies[name]; }
c = document.cookie.split('; ');
cookies = {};
for(i=c.length-1; i>=0; i--){
C = c[i].split('=');
cookies[C[0]] = C[1];
}
return cookies[name];
}
window.readCookie = readCookie; // or expose it however you want
})();
Run Code Online (Sandbox Code Playgroud)
我担心除了你可以自由使用.forEach哪种依赖于浏览器之外,确实没有比这种通用逻辑更快的方法(即使那时你也没有那么多保存)
您自己的示例略微压缩为120 bytes:
function read_cookie(k,r){return(r=RegExp('(^|; )'+encodeURIComponent(k)+'=([^;]*)').exec(document.cookie))?r[2]:null;}
Run Code Online (Sandbox Code Playgroud)
110 bytes如果你把它设为1个字母的函数名,你可以得到它,90 bytes如果你放弃了encodeURIComponent.
我已经得到它下来73 bytes,但要公平它的82 bytes命名时readCookie和102 bytes时再加入encodeURIComponent:
function C(k){return(document.cookie.match('(^|; )'+k+'=([^;]*)')||0)[2]}
Run Code Online (Sandbox Code Playgroud)
Mac*_*Mac 168
比目前最佳投票的答案更短,更可靠,更高效:
function getCookieValue(a) {
var b = document.cookie.match('(^|[^;]+)\\s*' + a + '\\s*=\\s*([^;]+)');
return b ? b.pop() : '';
}
Run Code Online (Sandbox Code Playgroud)
这里显示了各种方法的性能比较:
http://jsperf.com/get-cookie-value-regex-vs-array-functions
关于方法的一些说明:
正则表达式方法不仅是大多数浏览器中最快的方法,它还产生最短的函数.此外,应该指出的是,根据官方规范(RFC 2109),分隔文件中的cookie的分号后面的空格是可选的,并且可以说它不应该被依赖.此外,在等号(=)之前和之后允许使用空格,并且可以使该参数空白应该被分解为任何可靠的document.cookie解析器.上面的正则表达式解释了上述两种空白条件.
Jef*_* To 20
基于这个问题,我认为这个功能的一些假设/要求包括:
"foo:bar[0]"应该返回一个名为"foo:bar [0]"的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, '');
}
Run Code Online (Sandbox Code Playgroud)
当缩小时,达到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,'');}
Run Code Online (Sandbox Code Playgroud)
更新:如果您真的需要正则表达式解决方案:
function readCookie(name) {
return (name = new RegExp('(?:^|;\\s*)' + ('' + name).replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') + '=([^;]*)').exec(document.cookie)) && name[1];
}
Run Code Online (Sandbox Code Playgroud)
这会在构造RegExp对象之前转义 cookie名称中的任何特殊字符.缩小,这将达到134个字符(不包括函数名称):
function readCookie(n){return(n=new RegExp('(?:^|;\\s*)'+(''+n).replace(/[-[\]{}()*+?.,\\^$|#\s]/g,'\\$&')+'=([^;]*)').exec(document.cookie))&&n[1];}
Run Code Online (Sandbox Code Playgroud)
正如Rudu和cwolves在评论中指出的那样,正则表达式逃避正则表达式可以缩短几个字符.我认为保持逃避正则表达式一致(你可能在其他地方使用它)会很好,但他们的建议值得考虑.
这两个函数都不会处理,null或者undefined如果有一个名为"null"的cookie,readCookie(null)它将返回其值.如果您需要处理这种情况,请相应地调整代码.
小智 14
谷歌分析ga.js的代码
function c(a){
var d=[],
e=document.cookie.split(";");
a=RegExp("^\\s*"+a+"=\\s*(.*?)\\s*$");
for(var b=0;b<e.length;b++){
var f=e[b].match(a);
f&&d.push(f[1])
}
return d
}
Run Code Online (Sandbox Code Playgroud)
这个怎么样?
function getCookie(k){var v=document.cookie.match('(^|;) ?'+k+'=([^;]*)(;|$)');return v?v[2]:null}
Run Code Online (Sandbox Code Playgroud)
计算不带函数名的89个字节.
小智 5
这是一个您可以读取、写入、覆盖和删除 cookie 的对象。
var cookie = {
write : function (cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires="+d.toUTCString();
document.cookie = cname + "=" + cvalue + "; " + expires;
},
read : function (name) {
if (document.cookie.indexOf(name) > -1) {
return document.cookie.split(name)[1].split("; ")[0].substr(1)
} else {
return "";
}
},
delete : function (cname) {
var d = new Date();
d.setTime(d.getTime() - 1000);
var expires = "expires="+d.toUTCString();
document.cookie = cname + "=; " + expires;
}
};
Run Code Online (Sandbox Code Playgroud)
来了..干杯!
function getCookie(n) {
let a = `; ${document.cookie}`.match(`;\\s*${n}=([^;]+)`);
return a ? a[1] : '';
}
Run Code Online (Sandbox Code Playgroud)
请注意,我使用 ES6 的模板字符串来组成正则表达式。
以下函数将允许区分空字符串和未定义的 cookie。undefined与此处的其他一些答案不同,未定义的 cookie 将正确返回,而不是空字符串。
function getCookie(name) {
return (document.cookie.match('(^|;) *'+name+'=([^;]*)')||[])[2];
}
Run Code Online (Sandbox Code Playgroud)
以上在我检查过的所有浏览器上对我来说都很好,但正如@vanovm 在评论中提到的那样,根据规范,键/值可能被空格包围。因此,以下更符合标准。
function getCookie(name) {
return (document.cookie.match('(?:^|;)\\s*'+name.trim()+'\\s*=\\s*([^;]*?)\\s*(?:;|$)')||[])[1];
}
Run Code Online (Sandbox Code Playgroud)
现在是 2022 年,除了 Internet Explorer 之外的所有浏览器都支持URLSearchParamsAPI ( ^1 ) 和String.prototype.replaceAllAPI ( ^2 ),因此我们可以可怕地(ab)使用它们:
const cookies = new URLSearchParams(document.cookie.replaceAll('&', '%26').replaceAll('; ', '&'));
cookies.get('cookie name'); // returns undefined if not set, string otherwise
Run Code Online (Sandbox Code Playgroud)