Reading cookies the regular expression way

While taking a look on the 2nd 24ways article for 2009, I was really surprised to read that “The Web Storage API is basically cookies on steroids, a unhealthy dosage of steroids. Cookies are always a pain to work with. First of all you have the problem of setting, changing and deleting them. Typically solved by Googling and blindly relying on PPK’s solution. (bold is mine)

Of course, there’s nothing wrong with PPK’s solution. It works just fine. However, I always thought his readCookie() function was too verbose and complicated for no reason. It’s a very common example of someone desperately trying to avoid using a regular expression. I googled for “javascript read cookie” and to my surprise, all examples found in the first results were very similar. I never understood why even experienced developers are so scared of regular expressions. Anyway, if anyone wants a shorter function to read a cookie, here’s what I use:

function readCookie(name) {
    // Escape regexp special characters (thanks kangax!)
    name = name.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');

    var regex = new RegExp('(?:^|;)\\s?' + name + '=(.*?)(?:;|$)','i'),
        match = document.cookie.match(regex);

    return match && unescape(match[1]); // thanks James!
}

Update: Function updated, see comments below.

I’ve been using it for years and it hasn’t let me down. 🙂

Probably lots of other people have come up and posted something similar before me (I was actually very surprised that something like this isn’t mainstream), but I’m posting it just in case. 🙂

  • Surely, the regular expression match will always return either null or the result array (and a match’s length will never be zero). So, can’t you simply return:

    match && unescape(match[1])

    I agree with you about PPK’s solution being a bit too verbose; PPK’s JavaScript, IMO, is not his forte. He’s always been a DOM Guru in my books… His JS never really impressed me.

    Regular expressions FTW

  • It would probably make sense to escape name against regex meta characters. Looking at RFC2109, I see that characters allowed in cookie attribites are non-whitespace non-special ones (as defined in HTTP/1.1). HTTP/1.1 (RFC2068), in its turn, lists a set of special chars that appear to be not fully identical to special chars of regular expressions in ECMAScript. So… escaping names would be a good idea 🙂

    And in fact, I just tried it in console:

    document.cookie = ‘foo|bar=baz’;
    readCookie(‘foo|bar’); // “undefined”

    document.cookie = ‘foo*bar=baz’;
    readCookie(‘foo*bar’); // null

    PPK’s `readCookie` returns proper “baz” in both cases (not saying that we should start using his solution now, just that we could do better with regex-based variant; say add this to a function — `name = name.replace(/([.*+?^=!:${}()|[\]\/\\])/g, ‘\\$1’);`)

  • You guys are both sooooo right!

    Kangax, I can’t believe I missed that, gosh!

    Post updated. Thank you both!!

  • H

    There’s a reason actually that a JS developer always avoids regular expressions, and that is code speed and performace. Perhaps it won’t make much of a difference on your rig, but it all adds up making a website slower and slower on a netbook or older computer.

  • Have you actually tested that or are you just guessing?
    I think in most cases regular expressions are actually faster than string manipulation. Most JS frameworks even use them for simple case-insensitive string comparisions.

  • Why would you need “a shorter solution” ? PPK code has only 22 lines, and you can easily minify it.

    Why use regexp, if you don’t need to ? PPK’s code is much easier for humans to read, and thus is much less error prone. Speed is not an issue, too, because you maximum cookie size is only 4KB.

    If you want “more beautiful” cookie handling code and no new functions in global scope – wrap it into object, or just use mainstream js libraries (http://mootools.net/docs/core/Utilities/Cookie)

    _________
    p.s.: Some people, when confronted with a problem, think
    “I know, I’ll use regular expressions.” Now they have two problems.

  • DHKiefer

    Why not shave it down to a single line:

    return unescape((document.cookie.match(new RegExp(‘b’ + name.replace(/([^sw])/g,”\$1″) + ‘=(.*?)(?:;|$)’,’i’)) || [null,”])[1]);
    The only downside is that the function returns and the empty string (”) whether the cookie exists in the list or doesn’t (yours would return null if the cookie isn’t set, ” if it is, but empty). Also, much of the above can be eliminated by utilizing the word boundary marker and a simple negated character class.

  • Dylan Smith

    Thanks, this is great. Out of interest, what is the purpose of the ? in =(.*?). It seems redundant given that the * covers the zero character case.

    • When ? is placed after a quantifier it has a different role: It makes the quantifier lazy (=non-greedy).

      • Dylan Smith

        Ah, thanks for the knowledgebomb!

  • Pingback: satta matka()

  • Pingback: angara fahise()

  • Pingback: angara fahise()

  • Pingback: Daftar Agen Bola Terpercaya()

  • Pingback: lawyerforaccident.net()

  • Pingback: best steroids online site buy()

  • Pingback: Term Life Insurance()

  • Pingback: web hosting()

  • Pingback: locker codes()

  • Pingback: buy safe steroids()

  • Pingback: subways surfers()

  • Pingback: https://tribot.org/repository/script/id/619-exrunecrafter-monthly/()

  • Pingback: Dragon Ball Super Episode 46 English Sub()

  • Pingback: Criminal Record Database()

  • Pingback: roidpharm()

  • Pingback: moving house London()

  • Pingback: chữ ký số giá rẻ()