JavaScript can create, read, and delete cookies with the document.
The PHP $_COOKIE superglobal variable is used to retrieve a cookie value. It typically an associative array that contains a list of all the cookies values sent by the browser in the current request, keyed by cookie name.
Shorter, more reliable and more performant than the current best-voted answer:
const getCookieValue = (name) => (
document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)')?.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.
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]}
Based on the question, I believe some assumptions / requirements for this function include:
"foo:bar[0]"
should return a cookie (literally) named "foo:bar[0]";Under these assumptions, it's clear that encodeURIComponent
/ decodeURIComponent
should not be used; doing so assumes that the code that set the cookie also encoded it using these functions.
The regular expression approach gets problematic if the cookie name can contain special characters. jQuery.cookie works around this issue by encoding the cookie name (actually both name and value) when storing a cookie, and decoding the name when retrieving a cookie. A regular expression solution is below.
Unless you're only reading cookies you control completely, it would also be advisable to read cookies from document.cookie
directly and not cache the results, since there is no way to know if the cache is invalid without reading document.cookie
again.
(While accessing and parsing document.cookies
will be slightly slower than using a cache, it would not be as slow as reading other parts of the DOM, since cookies do not play a role in the DOM / render trees.)
Here goes the Code Golf answer, based on PPK's (loop-based) function:
function readCookie(name) {
name += '=';
for (var ca = document.cookie.split(/;\s*/), i = ca.length - 1; i >= 0; i--)
if (!ca[i].indexOf(name))
return ca[i].replace(name, '');
}
which when minified, comes to 128 characters (not counting the function name):
function readCookie(n){n+='=';for(var a=document.cookie.split(/;\s*/),i=a.length-1;i>=0;i--)if(!a[i].indexOf(n))return a[i].replace(n,'');}
Update: If you really want a regular expression solution:
function readCookie(name) {
return (name = new RegExp('(?:^|;\\s*)' + ('' + name).replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') + '=([^;]*)').exec(document.cookie)) && name[1];
}
This escapes any special characters in the cookie name before constructing the RegExp object. Minified, this comes to 134 characters (not counting the function name):
function readCookie(n){return(n=new RegExp('(?:^|;\\s*)'+(''+n).replace(/[-[\]{}()*+?.,\\^$|#\s]/g,'\\$&')+'=([^;]*)').exec(document.cookie))&&n[1];}
As Rudu and cwolves have pointed out in the comments, the regular-expression-escaping regex can be shortened by a few characters. I think it would be good to keep the escaping regex consistent (you may be using it elsewhere), but their suggestions are worth considering.
Both of these functions won't handle null
or undefined
, i.e. if there is a cookie named "null", readCookie(null)
will return its value. If you need to handle this case, adapt the code accordingly.
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
}
How about this one?
function getCookie(k){var v=document.cookie.match('(^|;) ?'+k+'=([^;]*)(;|$)');return v?v[2]:null}
Counted 89 bytes without the function name.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With