用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函数的大小感兴趣,并确保我拥有的解决方案是有效的。


当前回答

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

其他回答

它只会点击文档。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
})();

恐怕没有比这个通用逻辑更快的方法了,除非你可以自由地使用.forEach,它依赖于浏览器(即使这样你也不会节省那么多)

你自己的例子稍微压缩到120字节:

function read_cookie(k,r){return(r=RegExp('(^|; )'+encodeURIComponent(k)+'=([^;]*)').exec(document.cookie))?r[2]:null;}

如果函数名只有一个字母,可以达到110字节,如果去掉encodeURIComponent,可以达到90字节。

我已经把它减少到73个字节,但公平地说,当命名为readCookie时是82个字节,然后添加encodeURIComponent时是102个字节:

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

使用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字节。

为了真正消除尽可能多的膨胀,请考虑完全不使用包装器函数:

try {
    var myCookie = document.cookie.match('(^|;) *myCookie=([^;]*)')[2]
} catch (_) {
    // handle missing cookie
}

只要您熟悉RegEx,代码就相当干净且易于阅读。

现在是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

要在Map中按名称访问所有cookie:

const cookies = "a=b ; c = d ;e=";
const map = cookies.split(";").map((s) => s.split("=").map((s) => s.trim())).reduce((m, [k, v]) => (m.set(k, v), m), new Map());
console.log(map); //Map(3) {'a' => 'b', 'c' => 'd', 'e' => ''}
map.get("a"); //returns "b"
map.get("c"); //returns "d"
map.get("e"); //returns ""