用JavaScript读取cookie的最短、准确且跨浏览器兼容的方法是什么?

通常,在构建独立脚本(在那里我不能有任何外部依赖)时,我发现自己添加了一个读取cookie的函数,并且通常回退到QuirksMode.org readCookie()方法(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;
}

它确实起到了作用,但它很丑,而且每次都增加了相当多的膨胀。

jQuery的方法。Cookie使用类似这样的内容(经过修改,165字节,125字节缩小):

function read_cookie(key)
{
    var result;
    return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? (result[1]) : null;
}

请注意,这不是一场“代码高尔夫”比赛:我对减小readCookie函数的大小感兴趣,并确保我拥有的解决方案是有效的。


当前回答

下面的函数将允许区分空字符串和未定义的cookie。未定义cookie将正确返回未定义,而不是一个空字符串,不像这里的一些其他答案。

function getCookie(name) {
    return (document.cookie.match('(^|;) *'+name+'=([^;]*)')||[])[2];
}

在我检查的所有浏览器上,上面的工作都很好,但正如@vanovm在评论中提到的,根据规范,键/值可能被空格包围。因此,下面的代码更符合标准。

function getCookie(name) {
    return (document.cookie.match('(?:^|;)\\s*'+name.trim()+'\\s*=\\s*([^;]*?)\\s*(?:;|$)')||[])[1];
}

其他回答

这个怎么样?

function getCookie(k){var v=document.cookie.match('(^|;) ?'+k+'=([^;]*)(;|$)');return v?v[2]:null}

计数了89个字节,没有函数名。

代码来自谷歌analytics 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
}

使用cwolves的答案,但不使用闭包或预先计算的哈希:

// Golfed it a bit, too...
function readCookie(n){
  var c = document.cookie.split('; '),
      i = c.length,
      C;

  for(; i>0; i--){
     C = c[i].split('=');
     if(C[0] == n) return C[1];
  }
}

...和缩减……

function readCookie(n){var c=document.cookie.split('; '),i=c.length,C;for(;i>0;i--){C=c[i].split('=');if(C[0]==n)return C[1];}}

...等于127字节。

你可以验证一个cookie是否存在并且它有一个定义值:

function getCookie(cookiename) {
    if (typeof(cookiename) == 'string' && cookiename != '') {
        const COOKIES = document.cookie.split(';');
        for (i = 0; i < COOKIES.length; i++) {
            if (COOKIES[i].trim().startsWith(cookiename)) {
                return COOKIES[i].split('=')[1];
            }
        }
    }

    return null;
}

const COOKIE_EXAMPLE = getCookie('example');
if (COOKIE_EXAMPLE == 'stackoverflow') { ... }
// If is set a cookie named "example" with value "stackoverflow"
if (COOKIE_EXAMPLE != null) { ... }
// If is set a cookie named "example" ignoring the value

如果cookie不存在,则返回null。

现在是2022年,除了ie浏览器之外,所有东西都支持URLSearchParams API(^1)和String.prototype.replaceAll API(^2),所以我们可以可怕地(ab)使用它们:

const cookies = new URLSearchParams(document.cookie.replaceAll('&', '%26').replaceAll('; ', '&'));
cookies.get('cookie name'); // returns undefined if not set, string otherwise