What is the shortest function for reading a cookie by name in JavaScript?

前端 未结 15 1896
猫巷女王i
猫巷女王i 2020-11-22 17:17

What is the shortest, accurate, and cross-browser compatible method for reading a cookie in JavaScript?

Very often, while building stand-alone scri

相关标签:
15条回答
  • 2020-11-22 17:27

    Shorter, more reliable and more performant than the current best-voted answer:

    function getCookieValue(a) {
        var b = document.cookie.match('(^|;)\\s*' + a + '\\s*=\\s*([^;]+)');
        return b ? b.pop() : '';
    }
    

    A performance comparison of various approaches is shown here:

    http://jsperf.com/get-cookie-value-regex-vs-array-functions

    Some notes on approach:

    The regex approach is not only the fastest in most browsers, it yields the shortest function as well. Additionally it should be pointed out that according to the official spec (RFC 2109), the space after the semicolon which separates cookies in the document.cookie is optional and an argument could be made that it should not be relied upon. Additionally, whitespace is allowed before and after the equals sign (=) and an argument could be made that this potential whitespace should be factored into any reliable document.cookie parser. The regex above accounts for both of the above whitespace conditions.

    0 讨论(0)
  • 2020-11-22 17:30

    Using cwolves' answer, but not using a closure nor a pre-computed hash :

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

    ...and minifying...

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

    ...equals 127 bytes.

    0 讨论(0)
  • 2020-11-22 17:32

    code from google 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
    }
    
    0 讨论(0)
  • 2020-11-22 17:33

    This will only ever hit document.cookie ONE time. Every subsequent request will be instant.

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

    I'm afraid there really isn't a faster way than this general logic unless you're free to use .forEach which is browser dependent (even then you're not saving that much)

    Your own example slightly compressed to 120 bytes:

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

    You can get it to 110 bytes if you make it a 1-letter function name, 90 bytes if you drop the encodeURIComponent.

    I've gotten it down to 73 bytes, but to be fair it's 82 bytes when named readCookie and 102 bytes when then adding encodeURIComponent:

    function C(k){return(document.cookie.match('(^|; )'+k+'=([^;]*)')||0)[2]}
    
    0 讨论(0)
  • 2020-11-22 17:35

    To have all cookies accessible by name in a Map:

    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 ""
    
    0 讨论(0)
  • 2020-11-22 17:36

    Both of these functions look equally valid in terms of reading cookie. You can shave a few bytes off though (and it really is getting into Code Golf territory here):

    function readCookie(name) {
        var nameEQ = name + "=", ca = document.cookie.split(';'), i = 0, c;
        for(;i < ca.length;i++) {
            c = ca[i];
            while (c[0]==' ') c = c.substring(1);
            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length);
        }
        return null;
    }
    

    All I did with this is collapse all the variable declarations into one var statement, removed the unnecessary second arguments in calls to substring, and replace the one charAt call into an array dereference.

    This still isn't as short as the second function you provided, but even that can have a few bytes taken off:

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

    I changed the first sub-expression in the regular expression to be a capturing sub-expression, and changed the result[1] part to result[2] to coincide with this change; also removed the unnecessary parens around result[2].

    0 讨论(0)
提交回复
热议问题