用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。

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;
    }
};

其他回答

你可以验证一个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。

这个怎么样?

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

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

我的建议是:

function getCookie(name) {
   const cookieDict = document.cookie.split(';')
        .map((x)=>x.split('='))
        .reduce((accum,current) => { accum[current[0]]=current[1]; return accum;}, Object());
    return cookieDict[name];
}

上面的代码生成一个dict,该dict将cookie存储为键-值对(即cookidict),然后访问属性名以检索cookie。

这可以有效地表达为一句俏皮话,但这只适用于勇敢的人:

document.cookie.split(';').map((x)=>x.split('=')).reduce((accum,current) => { accum[current[0]]=current[1]; return accum;}, {})[name]

最好的方法是在页面加载时生成cookieDict,然后在整个页面生命周期中通过调用cookieDict['cookiename']来访问各个cookie。

这里是. .干杯!

function getCookie(n) {
    let a = `; ${document.cookie}`.match(`;\\s*${n}=([^;]+)`);
    return a ? a[1] : '';
}

注意,我使用了ES6的模板字符串来组成正则表达式。

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