Remove class based if a cookie is set [duplicate] - javascript

I have a getter to get the value from a cookie.
Now I have 2 cookies by the name shares= and by the name obligations= .
I want to make this getter only to get the values from the obligations cookie.
How do I do this? So the for splits the data into separate values and puts it in an array.
function getCookie1() {
// What do I have to add here to look only in the "obligations=" cookie?
// Because now it searches all the cookies.
var elements = document.cookie.split('=');
var obligations= elements[1].split('%');
for (var i = 0; i < obligations.length - 1; i++) {
var tmp = obligations[i].split('$');
addProduct1(tmp[0], tmp[1], tmp[2], tmp[3]);
}
}

One approach, which avoids iterating over an array, would be:
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
Walkthrough
Splitting a string by token will produce either, an array with one string (same value), in case token does not exist in a string, or an array with two strings , in case token is found in a string .
The first (left) element is string of what was before the token, and the second one (right) is what is string of what was after the token.
(NOTE: in case string starts with a token, first element is an empty string)
Considering that cookies are stored as follows:
"{name}={value}; {name}={value}; ..."
in order to retrieve specific cookie value, we just need to get string that is after "; {name}=" and before next ";". Before we do any processing, we prepend the cookies string with "; ", so that every cookie name, including the first one, is enclosed with "; " and "=":
"; {name}={value}; {name}={value}; ..."
Now, we can first split by "; {name}=", and if token is found in a cookie string (i.e. we have two elements), we will end up with second element being a string that begins with our cookie value. Then we pull that out from an array (i.e. pop), and repeat the same process, but now with ";" as a token, but this time pulling out the left string (i.e. shift) to get the actual token value.

I would prefer using a single regular expression match on the cookie:
window.getCookie = function(name) {
var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
if (match) return match[2];
}
OR Also we are able to use as a function , check below code.
function check_cookie_name(name)
{
var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
if (match) {
console.log(match[2]);
}
else{
console.log('--something went wrong---');
}
}
Improved thanks to Scott Jungwirth in the comments.

The methods in some of the other answers that use a regular expression do not cover all cases, particularly:
When the cookie is the last cookie. In this case there will not be a semicolon after the cookie value.
When another cookie name ends with the name being looked up. For example, you are looking for the cookie named "one", and there is a cookie named "done".
When the cookie name includes characters that are not interpreted as themselves when used in a regular expression unless they are preceded by a backslash.
The following method handles these cases:
function getCookie(name) {
function escape(s) { return s.replace(/([.*+?\^$(){}|\[\]\/\\])/g, '\\$1'); }
var match = document.cookie.match(RegExp('(?:^|;\\s*)' + escape(name) + '=([^;]*)'));
return match ? match[1] : null;
}
This will return null if the cookie is not found. It will return an empty string if the value of the cookie is empty.
Notes:
This function assumes cookie names are case sensitive.
document.cookie - When this appears on the right-hand side of an assignment, it represents a string containing a semicolon-separated list of cookies, which in turn are name=value pairs. There appears to be a single space after each semicolon.
String.prototype.match() - Returns null when no match is found. Returns an array when a match is found, and the element at index [1] is the value of the first matching group.
Regular Expression Notes:
(?:xxxx) - forms a non-matching group.
^ - matches the start of the string.
| - separates alternative patterns for the group.
;\\s* - matches one semi-colon followed by zero or more whitespace characters.
= - matches one equal sign.
(xxxx) - forms a matching group.
[^;]* - matches zero or more characters other than a semi-colon. This means it will match characters up to, but not including, a semi-colon or to the end of the string.

If you use jQuery I recommend you to use this plugin:
https://github.com/carhartl/jquery-cookie
https://github.com/carhartl/jquery-cookie/blob/master/jquery.cookie.js
<script type="text/javascript"
src="//cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js">
So you can read cookie like this:
var value = $.cookie("obligations");
Also you can write cookie:
$.cookie('obligations', 'new_value');
$.cookie('obligations', 'new_value', { expires: 14, path: '/' });
Delete cookie:
$.removeCookie('obligations');

Here is a one liner to get a cookie value with a specific name without the need of any external lib:
const value = ('; '+document.cookie).split(`; COOKIE_NAME=`).pop().split(';')[0];
This answer is based on kirlich's brilliant solution. The only compromise of this solution is, that you will get an empty string when the cookie does not exist. In most cases this should not be a deal breaker, though.

4 years later, ES6 way simpler version.
function getCookie(name) {
let cookie = {};
document.cookie.split(';').forEach(function(el) {
let [k,v] = el.split('=');
cookie[k.trim()] = v;
})
return cookie[name];
}
I have also created a gist to use it as a Cookie object. e.g., Cookie.set(name,value) and Cookie.get(name)
This read all cookies instead of scanning through. It's ok for small number of cookies.

I have modified the function that Jonathan provided here, by using regular expression you can get a cookie value by its name like this:
function getCookie(name){
var pattern = RegExp(name + "=.[^;]*")
var matched = document.cookie.match(pattern)
if(matched){
var cookie = matched[0].split('=')
return cookie[1]
}
return false
}
If it returns empty string it means that the cookie exists but has no value, if it returns false then the cookie doesn't exist. I hope this helps.

You can use js-cookie library to get and set JavaScript cookies.
Include to your HTML:
<script src="https://cdn.jsdelivr.net/npm/js-cookie#2/src/js.cookie.min.js"></script>
To create a Cookie:
Cookies.set('name', 'value');
To read a Cookie:
Cookies.get('name'); // => 'value'

A simple way :)
const cookieObj = new URLSearchParams(document.cookie.replaceAll("&", "%26").replaceAll("; ","&"))
cookieObj.get("your-cookie-name")

One liner to convert cookie into JavaScript Object or Map
Object.fromEntries(document.cookie.split('; ').map(v=>v.split(/=(.*)/s).map(decodeURIComponent)))
new Map(document.cookie.split('; ').map(v=>v.split(/=(.*)/s).map(decodeURIComponent)))

My one linear function to get the value cookie by its key.
cookie = key=>((new RegExp((key || '=')+'=(.*?); ','gm')).exec(document.cookie+'; ') ||['',null])[1]
Call cookie function as
cookie('some-key')

Here is a pretty short version
function getCookie(n) {
let a = `; ${document.cookie}`.match(`;\\s*${n}=([^;]+)`);
return a ? a[1] : '';
}
Note that I made use of ES6's template strings to compose the regex expression.

I know it is an old question but I came across this problem too. Just for the record, There is a little API in developers mozilla web page.
Yoy can get any cookie by name using only JS. The code is also cleaner IMHO (except for the long line, that I'm sure you can easily fix).
function getCookie(sKey) {
if (!sKey) { return null; }
return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
}
As stated in the comments be aware that this method assumes that the key and value were encoded using encodeURIComponent(). Remove decode & encodeURIComponent() if the key and value of the cookie were not encoded.

function getCookie(name) {
var pair = document.cookie.split('; ').find(x => x.startsWith(name+'='));
if (pair)
return pair.split('=')[1]
}

kirlich gave a good solution. However, it fails when there are two cookie values with similar names, here is a simple fix for this situation:
function getCookie(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length >= 2) return parts.pop().split(";").shift();
}

Use object.defineProperty
With this, you can easily access cookies
Object.defineProperty(window, "Cookies", {
get: function() {
return document.cookie.split(';').reduce(function(cookies, cookie) {
cookies[cookie.split("=")[0]] = unescape(cookie.split("=")[1]);
return cookies
}, {});
}
});
From now on you can just do:
alert( Cookies.obligations );
This will automatically update too, so if you change a cookie, the Cookies will change too.

It seems to me you could split the cookie key-value pairs into an array and base your search on that:
var obligations = getCookieData("obligations");
Which runs the following:
function getCookieData( name ) {
var pairs = document.cookie.split("; "),
count = pairs.length, parts;
while ( count-- ) {
parts = pairs[count].split("=");
if ( parts[0] === name )
return parts[1];
}
return false;
}
Fiddle: http://jsfiddle.net/qFmPc/
Or possibly even the following:
function getCookieData( name ) {
var patrn = new RegExp( "^" + name + "=(.*?);" ),
patr2 = new RegExp( " " + name + "=(.*?);" );
if ( match = (document.cookie.match(patrn) || document.cookie.match(patr2)) )
return match[1];
return false;
}

always works well:
function getCookie(cname) {
var name = cname + "=",
ca = document.cookie.split(';'),
i,
c,
ca_length = ca.length;
for (i = 0; i < ca_length; i += 1) {
c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf(name) !== -1) {
return c.substring(name.length, c.length);
}
}
return "";
}
function setCookie(variable, value, expires_seconds) {
var d = new Date();
d = new Date(d.getTime() + 1000 * expires_seconds);
document.cookie = variable + '=' + value + '; expires=' + d.toGMTString() + ';';
}
No requirements for jQuery or anything. Pure old good JavaScript.

Simple function for Get cookie with cookie name:
function getCookie(cn) {
var name = cn+"=";
var allCookie = decodeURIComponent(document.cookie).split(';');
var cval = [];
for(var i=0; i < allCookie.length; i++) {
if (allCookie[i].trim().indexOf(name) == 0) {
cval = allCookie[i].trim().split("=");
}
}
return (cval.length > 0) ? cval[1] : "";
}

Apparently MDN has never heard of the word-boundary regex character class \b, which matches contiguous \w+ that is bounded on either side with \W+:
getCookie = function(name) {
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return r ? r[1] : null;
};
var obligations = getCookie('obligations');

In my projects I use following function to access cookies by name
function getCookie(cookie) {
return document.cookie.split(';').reduce(function(prev, c) {
var arr = c.split('=');
return (arr[0].trim() === cookie) ? arr[1] : prev;
}, undefined);
}

There are already nice answers here for getting the cookie,However here is my own solution :
function getcookie(cookiename){
var cookiestring = document.cookie;
var cookiearray = cookiestring.split(';');
for(var i =0 ; i < cookiearray.length ; ++i){
if(cookiearray[i].trim().match('^'+cookiename+'=')){
return cookiearray[i].replace(`${cookiename}=`,'').trim();
}
} return null;
}
usage :`
getcookie('session_id');
// gets cookie with name session_id

set by javascript
document.cookie = 'cookiename=tesing';
get by jquery with the jquery-cookie plugin
var value = $.cookie("cookiename");
alert(value);

function getCookie(cname) {
var name = cname + "=";
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);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
Pass the cookie name to getCookie() function to get it's value

My solution is this:
function getCookieValue(cookieName) {
var ca = document.cookie.split('; ');
return _.find(ca, function (cookie) {
return cookie.indexOf(cookieName) === 0;
});
}
This function uses the Underscorejs _.find-function. Returns undefined if cookie name doesn't exist

I have done it this way. so that i get an object to access to separate the values.With this u can pass the cookie to the parent and then you can access your values by the keys like
var cookies=getCookieVal(mycookie);
alert(cookies.mykey);
function getCookieVal(parent) {
var cookievalue = $.cookie(parent).split('&');
var obj = {};
$.each(cookievalue, function (i, v) {
var key = v.substr(0, v.indexOf("="));
var val = v.substr(v.indexOf("=") + 1, v.length);
obj[key] = val;
});
return obj;
}

Just use the following function (a pure javascript code)
const getCookie = (name) => {
const cookies = Object.assign({}, ...document.cookie.split('; ').map(cookie => {
const name = cookie.split('=')[0];
const value = cookie.split('=')[1];
return {[name]: value};
}));
return cookies[name];
};

I wrote something that might be easy to use, If anyone has some things to add, feel free to do so.
function getcookie(name = '') {
let cookies = document.cookie;
let cookiestore = {};
cookies = cookies.split(";");
if (cookies[0] == "" && cookies[0][0] == undefined) {
return undefined;
}
cookies.forEach(function(cookie) {
cookie = cookie.split(/=(.+)/);
if (cookie[0].substr(0, 1) == ' ') {
cookie[0] = cookie[0].substr(1);
}
cookiestore[cookie[0]] = cookie[1];
});
return (name !== '' ? cookiestore[name] : cookiestore);
}
Usage
getcookie() - returns an object with all cookies on the web page.
getcookie('myCookie') - returns the value of the cookie myCookie from the cookie object, otherwise returns undefined if the cookie is empty or not set.
Example
// Have some cookies :-)
document.cookie = "myCookies=delicious";
document.cookie = "myComputer=good";
document.cookie = "myBrowser=RAM hungry";
// Read them
console.log( "My cookies are " + getcookie('myCookie') );
// Outputs: My cookies are delicious
console.log( "My computer is " + getcookie('myComputer') );
// Outputs: My computer is good
console.log( "My browser is " + getcookie('myBrowser') );
// Outputs: My browser is RAM hungry
console.log( getcookie() );
// Outputs: {myCookie: "delicious", myComputer: "good", myBrowser: "RAM hungry"}
// (does cookie exist?)
if (getcookie('hidden_cookie')) {
console.log('Hidden cookie was found!');
} else {
console.log('Still no cookie :-(');
}
// (do any cookies exist?)
if (getcookie()) {
console.log("You've got cookies to eat!");
} else {
console.log('No cookies for today :-(');
}

A functional approach to find existing cookies. It returns an array, so it supports multiple occurrences of the same name. It doesn't support partial key matching, but it's trivial to replace the === in the filter with a regex.
function getCookie(needle) {
return document.cookie.split(';').map(function(cookiestring) {
cs = cookiestring.trim().split('=');
if(cs.length === 2) {
return {'name' : cs[0], 'value' : cs[1]};
} else {
return {'name' : '', 'value' : ''};
}
})
.filter(function(cookieObject) {
return (cookieObject.name === needle);
});
}

Get cookie by name just pass the name of cookie to below function
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}

Related

How can I console.log a Specific cookie with document.cookie without having the value? [duplicate]

I have a getter to get the value from a cookie.
Now I have 2 cookies by the name shares= and by the name obligations= .
I want to make this getter only to get the values from the obligations cookie.
How do I do this? So the for splits the data into separate values and puts it in an array.
function getCookie1() {
// What do I have to add here to look only in the "obligations=" cookie?
// Because now it searches all the cookies.
var elements = document.cookie.split('=');
var obligations= elements[1].split('%');
for (var i = 0; i < obligations.length - 1; i++) {
var tmp = obligations[i].split('$');
addProduct1(tmp[0], tmp[1], tmp[2], tmp[3]);
}
}
One approach, which avoids iterating over an array, would be:
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
Walkthrough
Splitting a string by token will produce either, an array with one string (same value), in case token does not exist in a string, or an array with two strings , in case token is found in a string .
The first (left) element is string of what was before the token, and the second one (right) is what is string of what was after the token.
(NOTE: in case string starts with a token, first element is an empty string)
Considering that cookies are stored as follows:
"{name}={value}; {name}={value}; ..."
in order to retrieve specific cookie value, we just need to get string that is after "; {name}=" and before next ";". Before we do any processing, we prepend the cookies string with "; ", so that every cookie name, including the first one, is enclosed with "; " and "=":
"; {name}={value}; {name}={value}; ..."
Now, we can first split by "; {name}=", and if token is found in a cookie string (i.e. we have two elements), we will end up with second element being a string that begins with our cookie value. Then we pull that out from an array (i.e. pop), and repeat the same process, but now with ";" as a token, but this time pulling out the left string (i.e. shift) to get the actual token value.
I would prefer using a single regular expression match on the cookie:
window.getCookie = function(name) {
var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
if (match) return match[2];
}
OR Also we are able to use as a function , check below code.
function check_cookie_name(name)
{
var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
if (match) {
console.log(match[2]);
}
else{
console.log('--something went wrong---');
}
}
Improved thanks to Scott Jungwirth in the comments.
The methods in some of the other answers that use a regular expression do not cover all cases, particularly:
When the cookie is the last cookie. In this case there will not be a semicolon after the cookie value.
When another cookie name ends with the name being looked up. For example, you are looking for the cookie named "one", and there is a cookie named "done".
When the cookie name includes characters that are not interpreted as themselves when used in a regular expression unless they are preceded by a backslash.
The following method handles these cases:
function getCookie(name) {
function escape(s) { return s.replace(/([.*+?\^$(){}|\[\]\/\\])/g, '\\$1'); }
var match = document.cookie.match(RegExp('(?:^|;\\s*)' + escape(name) + '=([^;]*)'));
return match ? match[1] : null;
}
This will return null if the cookie is not found. It will return an empty string if the value of the cookie is empty.
Notes:
This function assumes cookie names are case sensitive.
document.cookie - When this appears on the right-hand side of an assignment, it represents a string containing a semicolon-separated list of cookies, which in turn are name=value pairs. There appears to be a single space after each semicolon.
String.prototype.match() - Returns null when no match is found. Returns an array when a match is found, and the element at index [1] is the value of the first matching group.
Regular Expression Notes:
(?:xxxx) - forms a non-matching group.
^ - matches the start of the string.
| - separates alternative patterns for the group.
;\\s* - matches one semi-colon followed by zero or more whitespace characters.
= - matches one equal sign.
(xxxx) - forms a matching group.
[^;]* - matches zero or more characters other than a semi-colon. This means it will match characters up to, but not including, a semi-colon or to the end of the string.
If you use jQuery I recommend you to use this plugin:
https://github.com/carhartl/jquery-cookie
https://github.com/carhartl/jquery-cookie/blob/master/jquery.cookie.js
<script type="text/javascript"
src="//cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js">
So you can read cookie like this:
var value = $.cookie("obligations");
Also you can write cookie:
$.cookie('obligations', 'new_value');
$.cookie('obligations', 'new_value', { expires: 14, path: '/' });
Delete cookie:
$.removeCookie('obligations');
Here is a one liner to get a cookie value with a specific name without the need of any external lib:
const value = ('; '+document.cookie).split(`; COOKIE_NAME=`).pop().split(';')[0];
This answer is based on kirlich's brilliant solution. The only compromise of this solution is, that you will get an empty string when the cookie does not exist. In most cases this should not be a deal breaker, though.
4 years later, ES6 way simpler version.
function getCookie(name) {
let cookie = {};
document.cookie.split(';').forEach(function(el) {
let [k,v] = el.split('=');
cookie[k.trim()] = v;
})
return cookie[name];
}
I have also created a gist to use it as a Cookie object. e.g., Cookie.set(name,value) and Cookie.get(name)
This read all cookies instead of scanning through. It's ok for small number of cookies.
I have modified the function that Jonathan provided here, by using regular expression you can get a cookie value by its name like this:
function getCookie(name){
var pattern = RegExp(name + "=.[^;]*")
var matched = document.cookie.match(pattern)
if(matched){
var cookie = matched[0].split('=')
return cookie[1]
}
return false
}
If it returns empty string it means that the cookie exists but has no value, if it returns false then the cookie doesn't exist. I hope this helps.
You can use js-cookie library to get and set JavaScript cookies.
Include to your HTML:
<script src="https://cdn.jsdelivr.net/npm/js-cookie#2/src/js.cookie.min.js"></script>
To create a Cookie:
Cookies.set('name', 'value');
To read a Cookie:
Cookies.get('name'); // => 'value'
A simple way :)
const cookieObj = new URLSearchParams(document.cookie.replaceAll("&", "%26").replaceAll("; ","&"))
cookieObj.get("your-cookie-name")
One liner to convert cookie into JavaScript Object or Map
Object.fromEntries(document.cookie.split('; ').map(v=>v.split(/=(.*)/s).map(decodeURIComponent)))
new Map(document.cookie.split('; ').map(v=>v.split(/=(.*)/s).map(decodeURIComponent)))
My one linear function to get the value cookie by its key.
cookie = key=>((new RegExp((key || '=')+'=(.*?); ','gm')).exec(document.cookie+'; ') ||['',null])[1]
Call cookie function as
cookie('some-key')
Here is a pretty short version
function getCookie(n) {
let a = `; ${document.cookie}`.match(`;\\s*${n}=([^;]+)`);
return a ? a[1] : '';
}
Note that I made use of ES6's template strings to compose the regex expression.
I know it is an old question but I came across this problem too. Just for the record, There is a little API in developers mozilla web page.
Yoy can get any cookie by name using only JS. The code is also cleaner IMHO (except for the long line, that I'm sure you can easily fix).
function getCookie(sKey) {
if (!sKey) { return null; }
return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
}
As stated in the comments be aware that this method assumes that the key and value were encoded using encodeURIComponent(). Remove decode & encodeURIComponent() if the key and value of the cookie were not encoded.
function getCookie(name) {
var pair = document.cookie.split('; ').find(x => x.startsWith(name+'='));
if (pair)
return pair.split('=')[1]
}
kirlich gave a good solution. However, it fails when there are two cookie values with similar names, here is a simple fix for this situation:
function getCookie(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length >= 2) return parts.pop().split(";").shift();
}
Use object.defineProperty
With this, you can easily access cookies
Object.defineProperty(window, "Cookies", {
get: function() {
return document.cookie.split(';').reduce(function(cookies, cookie) {
cookies[cookie.split("=")[0]] = unescape(cookie.split("=")[1]);
return cookies
}, {});
}
});
From now on you can just do:
alert( Cookies.obligations );
This will automatically update too, so if you change a cookie, the Cookies will change too.
It seems to me you could split the cookie key-value pairs into an array and base your search on that:
var obligations = getCookieData("obligations");
Which runs the following:
function getCookieData( name ) {
var pairs = document.cookie.split("; "),
count = pairs.length, parts;
while ( count-- ) {
parts = pairs[count].split("=");
if ( parts[0] === name )
return parts[1];
}
return false;
}
Fiddle: http://jsfiddle.net/qFmPc/
Or possibly even the following:
function getCookieData( name ) {
var patrn = new RegExp( "^" + name + "=(.*?);" ),
patr2 = new RegExp( " " + name + "=(.*?);" );
if ( match = (document.cookie.match(patrn) || document.cookie.match(patr2)) )
return match[1];
return false;
}
always works well:
function getCookie(cname) {
var name = cname + "=",
ca = document.cookie.split(';'),
i,
c,
ca_length = ca.length;
for (i = 0; i < ca_length; i += 1) {
c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf(name) !== -1) {
return c.substring(name.length, c.length);
}
}
return "";
}
function setCookie(variable, value, expires_seconds) {
var d = new Date();
d = new Date(d.getTime() + 1000 * expires_seconds);
document.cookie = variable + '=' + value + '; expires=' + d.toGMTString() + ';';
}
No requirements for jQuery or anything. Pure old good JavaScript.
Simple function for Get cookie with cookie name:
function getCookie(cn) {
var name = cn+"=";
var allCookie = decodeURIComponent(document.cookie).split(';');
var cval = [];
for(var i=0; i < allCookie.length; i++) {
if (allCookie[i].trim().indexOf(name) == 0) {
cval = allCookie[i].trim().split("=");
}
}
return (cval.length > 0) ? cval[1] : "";
}
Apparently MDN has never heard of the word-boundary regex character class \b, which matches contiguous \w+ that is bounded on either side with \W+:
getCookie = function(name) {
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return r ? r[1] : null;
};
var obligations = getCookie('obligations');
In my projects I use following function to access cookies by name
function getCookie(cookie) {
return document.cookie.split(';').reduce(function(prev, c) {
var arr = c.split('=');
return (arr[0].trim() === cookie) ? arr[1] : prev;
}, undefined);
}
There are already nice answers here for getting the cookie,However here is my own solution :
function getcookie(cookiename){
var cookiestring = document.cookie;
var cookiearray = cookiestring.split(';');
for(var i =0 ; i < cookiearray.length ; ++i){
if(cookiearray[i].trim().match('^'+cookiename+'=')){
return cookiearray[i].replace(`${cookiename}=`,'').trim();
}
} return null;
}
usage :`
getcookie('session_id');
// gets cookie with name session_id
set by javascript
document.cookie = 'cookiename=tesing';
get by jquery with the jquery-cookie plugin
var value = $.cookie("cookiename");
alert(value);
function getCookie(cname) {
var name = cname + "=";
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);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
Pass the cookie name to getCookie() function to get it's value
My solution is this:
function getCookieValue(cookieName) {
var ca = document.cookie.split('; ');
return _.find(ca, function (cookie) {
return cookie.indexOf(cookieName) === 0;
});
}
This function uses the Underscorejs _.find-function. Returns undefined if cookie name doesn't exist
I have done it this way. so that i get an object to access to separate the values.With this u can pass the cookie to the parent and then you can access your values by the keys like
var cookies=getCookieVal(mycookie);
alert(cookies.mykey);
function getCookieVal(parent) {
var cookievalue = $.cookie(parent).split('&');
var obj = {};
$.each(cookievalue, function (i, v) {
var key = v.substr(0, v.indexOf("="));
var val = v.substr(v.indexOf("=") + 1, v.length);
obj[key] = val;
});
return obj;
}
Just use the following function (a pure javascript code)
const getCookie = (name) => {
const cookies = Object.assign({}, ...document.cookie.split('; ').map(cookie => {
const name = cookie.split('=')[0];
const value = cookie.split('=')[1];
return {[name]: value};
}));
return cookies[name];
};
I wrote something that might be easy to use, If anyone has some things to add, feel free to do so.
function getcookie(name = '') {
let cookies = document.cookie;
let cookiestore = {};
cookies = cookies.split(";");
if (cookies[0] == "" && cookies[0][0] == undefined) {
return undefined;
}
cookies.forEach(function(cookie) {
cookie = cookie.split(/=(.+)/);
if (cookie[0].substr(0, 1) == ' ') {
cookie[0] = cookie[0].substr(1);
}
cookiestore[cookie[0]] = cookie[1];
});
return (name !== '' ? cookiestore[name] : cookiestore);
}
Usage
getcookie() - returns an object with all cookies on the web page.
getcookie('myCookie') - returns the value of the cookie myCookie from the cookie object, otherwise returns undefined if the cookie is empty or not set.
Example
// Have some cookies :-)
document.cookie = "myCookies=delicious";
document.cookie = "myComputer=good";
document.cookie = "myBrowser=RAM hungry";
// Read them
console.log( "My cookies are " + getcookie('myCookie') );
// Outputs: My cookies are delicious
console.log( "My computer is " + getcookie('myComputer') );
// Outputs: My computer is good
console.log( "My browser is " + getcookie('myBrowser') );
// Outputs: My browser is RAM hungry
console.log( getcookie() );
// Outputs: {myCookie: "delicious", myComputer: "good", myBrowser: "RAM hungry"}
// (does cookie exist?)
if (getcookie('hidden_cookie')) {
console.log('Hidden cookie was found!');
} else {
console.log('Still no cookie :-(');
}
// (do any cookies exist?)
if (getcookie()) {
console.log("You've got cookies to eat!");
} else {
console.log('No cookies for today :-(');
}
A functional approach to find existing cookies. It returns an array, so it supports multiple occurrences of the same name. It doesn't support partial key matching, but it's trivial to replace the === in the filter with a regex.
function getCookie(needle) {
return document.cookie.split(';').map(function(cookiestring) {
cs = cookiestring.trim().split('=');
if(cs.length === 2) {
return {'name' : cs[0], 'value' : cs[1]};
} else {
return {'name' : '', 'value' : ''};
}
})
.filter(function(cookieObject) {
return (cookieObject.name === needle);
});
}
Get cookie by name just pass the name of cookie to below function
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}

How to get the a sting in javascipt? [duplicate]

I have a getter to get the value from a cookie.
Now I have 2 cookies by the name shares= and by the name obligations= .
I want to make this getter only to get the values from the obligations cookie.
How do I do this? So the for splits the data into separate values and puts it in an array.
function getCookie1() {
// What do I have to add here to look only in the "obligations=" cookie?
// Because now it searches all the cookies.
var elements = document.cookie.split('=');
var obligations= elements[1].split('%');
for (var i = 0; i < obligations.length - 1; i++) {
var tmp = obligations[i].split('$');
addProduct1(tmp[0], tmp[1], tmp[2], tmp[3]);
}
}
One approach, which avoids iterating over an array, would be:
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
Walkthrough
Splitting a string by token will produce either, an array with one string (same value), in case token does not exist in a string, or an array with two strings , in case token is found in a string .
The first (left) element is string of what was before the token, and the second one (right) is what is string of what was after the token.
(NOTE: in case string starts with a token, first element is an empty string)
Considering that cookies are stored as follows:
"{name}={value}; {name}={value}; ..."
in order to retrieve specific cookie value, we just need to get string that is after "; {name}=" and before next ";". Before we do any processing, we prepend the cookies string with "; ", so that every cookie name, including the first one, is enclosed with "; " and "=":
"; {name}={value}; {name}={value}; ..."
Now, we can first split by "; {name}=", and if token is found in a cookie string (i.e. we have two elements), we will end up with second element being a string that begins with our cookie value. Then we pull that out from an array (i.e. pop), and repeat the same process, but now with ";" as a token, but this time pulling out the left string (i.e. shift) to get the actual token value.
I would prefer using a single regular expression match on the cookie:
window.getCookie = function(name) {
var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
if (match) return match[2];
}
OR Also we are able to use as a function , check below code.
function check_cookie_name(name)
{
var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
if (match) {
console.log(match[2]);
}
else{
console.log('--something went wrong---');
}
}
Improved thanks to Scott Jungwirth in the comments.
The methods in some of the other answers that use a regular expression do not cover all cases, particularly:
When the cookie is the last cookie. In this case there will not be a semicolon after the cookie value.
When another cookie name ends with the name being looked up. For example, you are looking for the cookie named "one", and there is a cookie named "done".
When the cookie name includes characters that are not interpreted as themselves when used in a regular expression unless they are preceded by a backslash.
The following method handles these cases:
function getCookie(name) {
function escape(s) { return s.replace(/([.*+?\^$(){}|\[\]\/\\])/g, '\\$1'); }
var match = document.cookie.match(RegExp('(?:^|;\\s*)' + escape(name) + '=([^;]*)'));
return match ? match[1] : null;
}
This will return null if the cookie is not found. It will return an empty string if the value of the cookie is empty.
Notes:
This function assumes cookie names are case sensitive.
document.cookie - When this appears on the right-hand side of an assignment, it represents a string containing a semicolon-separated list of cookies, which in turn are name=value pairs. There appears to be a single space after each semicolon.
String.prototype.match() - Returns null when no match is found. Returns an array when a match is found, and the element at index [1] is the value of the first matching group.
Regular Expression Notes:
(?:xxxx) - forms a non-matching group.
^ - matches the start of the string.
| - separates alternative patterns for the group.
;\\s* - matches one semi-colon followed by zero or more whitespace characters.
= - matches one equal sign.
(xxxx) - forms a matching group.
[^;]* - matches zero or more characters other than a semi-colon. This means it will match characters up to, but not including, a semi-colon or to the end of the string.
If you use jQuery I recommend you to use this plugin:
https://github.com/carhartl/jquery-cookie
https://github.com/carhartl/jquery-cookie/blob/master/jquery.cookie.js
<script type="text/javascript"
src="//cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js">
So you can read cookie like this:
var value = $.cookie("obligations");
Also you can write cookie:
$.cookie('obligations', 'new_value');
$.cookie('obligations', 'new_value', { expires: 14, path: '/' });
Delete cookie:
$.removeCookie('obligations');
Here is a one liner to get a cookie value with a specific name without the need of any external lib:
const value = ('; '+document.cookie).split(`; COOKIE_NAME=`).pop().split(';')[0];
This answer is based on kirlich's brilliant solution. The only compromise of this solution is, that you will get an empty string when the cookie does not exist. In most cases this should not be a deal breaker, though.
4 years later, ES6 way simpler version.
function getCookie(name) {
let cookie = {};
document.cookie.split(';').forEach(function(el) {
let [k,v] = el.split('=');
cookie[k.trim()] = v;
})
return cookie[name];
}
I have also created a gist to use it as a Cookie object. e.g., Cookie.set(name,value) and Cookie.get(name)
This read all cookies instead of scanning through. It's ok for small number of cookies.
I have modified the function that Jonathan provided here, by using regular expression you can get a cookie value by its name like this:
function getCookie(name){
var pattern = RegExp(name + "=.[^;]*")
var matched = document.cookie.match(pattern)
if(matched){
var cookie = matched[0].split('=')
return cookie[1]
}
return false
}
If it returns empty string it means that the cookie exists but has no value, if it returns false then the cookie doesn't exist. I hope this helps.
You can use js-cookie library to get and set JavaScript cookies.
Include to your HTML:
<script src="https://cdn.jsdelivr.net/npm/js-cookie#2/src/js.cookie.min.js"></script>
To create a Cookie:
Cookies.set('name', 'value');
To read a Cookie:
Cookies.get('name'); // => 'value'
A simple way :)
const cookieObj = new URLSearchParams(document.cookie.replaceAll("&", "%26").replaceAll("; ","&"))
cookieObj.get("your-cookie-name")
One liner to convert cookie into JavaScript Object or Map
Object.fromEntries(document.cookie.split('; ').map(v=>v.split(/=(.*)/s).map(decodeURIComponent)))
new Map(document.cookie.split('; ').map(v=>v.split(/=(.*)/s).map(decodeURIComponent)))
My one linear function to get the value cookie by its key.
cookie = key=>((new RegExp((key || '=')+'=(.*?); ','gm')).exec(document.cookie+'; ') ||['',null])[1]
Call cookie function as
cookie('some-key')
Here is a pretty short version
function getCookie(n) {
let a = `; ${document.cookie}`.match(`;\\s*${n}=([^;]+)`);
return a ? a[1] : '';
}
Note that I made use of ES6's template strings to compose the regex expression.
I know it is an old question but I came across this problem too. Just for the record, There is a little API in developers mozilla web page.
Yoy can get any cookie by name using only JS. The code is also cleaner IMHO (except for the long line, that I'm sure you can easily fix).
function getCookie(sKey) {
if (!sKey) { return null; }
return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
}
As stated in the comments be aware that this method assumes that the key and value were encoded using encodeURIComponent(). Remove decode & encodeURIComponent() if the key and value of the cookie were not encoded.
function getCookie(name) {
var pair = document.cookie.split('; ').find(x => x.startsWith(name+'='));
if (pair)
return pair.split('=')[1]
}
kirlich gave a good solution. However, it fails when there are two cookie values with similar names, here is a simple fix for this situation:
function getCookie(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length >= 2) return parts.pop().split(";").shift();
}
Use object.defineProperty
With this, you can easily access cookies
Object.defineProperty(window, "Cookies", {
get: function() {
return document.cookie.split(';').reduce(function(cookies, cookie) {
cookies[cookie.split("=")[0]] = unescape(cookie.split("=")[1]);
return cookies
}, {});
}
});
From now on you can just do:
alert( Cookies.obligations );
This will automatically update too, so if you change a cookie, the Cookies will change too.
It seems to me you could split the cookie key-value pairs into an array and base your search on that:
var obligations = getCookieData("obligations");
Which runs the following:
function getCookieData( name ) {
var pairs = document.cookie.split("; "),
count = pairs.length, parts;
while ( count-- ) {
parts = pairs[count].split("=");
if ( parts[0] === name )
return parts[1];
}
return false;
}
Fiddle: http://jsfiddle.net/qFmPc/
Or possibly even the following:
function getCookieData( name ) {
var patrn = new RegExp( "^" + name + "=(.*?);" ),
patr2 = new RegExp( " " + name + "=(.*?);" );
if ( match = (document.cookie.match(patrn) || document.cookie.match(patr2)) )
return match[1];
return false;
}
always works well:
function getCookie(cname) {
var name = cname + "=",
ca = document.cookie.split(';'),
i,
c,
ca_length = ca.length;
for (i = 0; i < ca_length; i += 1) {
c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf(name) !== -1) {
return c.substring(name.length, c.length);
}
}
return "";
}
function setCookie(variable, value, expires_seconds) {
var d = new Date();
d = new Date(d.getTime() + 1000 * expires_seconds);
document.cookie = variable + '=' + value + '; expires=' + d.toGMTString() + ';';
}
No requirements for jQuery or anything. Pure old good JavaScript.
Simple function for Get cookie with cookie name:
function getCookie(cn) {
var name = cn+"=";
var allCookie = decodeURIComponent(document.cookie).split(';');
var cval = [];
for(var i=0; i < allCookie.length; i++) {
if (allCookie[i].trim().indexOf(name) == 0) {
cval = allCookie[i].trim().split("=");
}
}
return (cval.length > 0) ? cval[1] : "";
}
Apparently MDN has never heard of the word-boundary regex character class \b, which matches contiguous \w+ that is bounded on either side with \W+:
getCookie = function(name) {
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return r ? r[1] : null;
};
var obligations = getCookie('obligations');
In my projects I use following function to access cookies by name
function getCookie(cookie) {
return document.cookie.split(';').reduce(function(prev, c) {
var arr = c.split('=');
return (arr[0].trim() === cookie) ? arr[1] : prev;
}, undefined);
}
There are already nice answers here for getting the cookie,However here is my own solution :
function getcookie(cookiename){
var cookiestring = document.cookie;
var cookiearray = cookiestring.split(';');
for(var i =0 ; i < cookiearray.length ; ++i){
if(cookiearray[i].trim().match('^'+cookiename+'=')){
return cookiearray[i].replace(`${cookiename}=`,'').trim();
}
} return null;
}
usage :`
getcookie('session_id');
// gets cookie with name session_id
set by javascript
document.cookie = 'cookiename=tesing';
get by jquery with the jquery-cookie plugin
var value = $.cookie("cookiename");
alert(value);
function getCookie(cname) {
var name = cname + "=";
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);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
Pass the cookie name to getCookie() function to get it's value
My solution is this:
function getCookieValue(cookieName) {
var ca = document.cookie.split('; ');
return _.find(ca, function (cookie) {
return cookie.indexOf(cookieName) === 0;
});
}
This function uses the Underscorejs _.find-function. Returns undefined if cookie name doesn't exist
I have done it this way. so that i get an object to access to separate the values.With this u can pass the cookie to the parent and then you can access your values by the keys like
var cookies=getCookieVal(mycookie);
alert(cookies.mykey);
function getCookieVal(parent) {
var cookievalue = $.cookie(parent).split('&');
var obj = {};
$.each(cookievalue, function (i, v) {
var key = v.substr(0, v.indexOf("="));
var val = v.substr(v.indexOf("=") + 1, v.length);
obj[key] = val;
});
return obj;
}
Just use the following function (a pure javascript code)
const getCookie = (name) => {
const cookies = Object.assign({}, ...document.cookie.split('; ').map(cookie => {
const name = cookie.split('=')[0];
const value = cookie.split('=')[1];
return {[name]: value};
}));
return cookies[name];
};
I wrote something that might be easy to use, If anyone has some things to add, feel free to do so.
function getcookie(name = '') {
let cookies = document.cookie;
let cookiestore = {};
cookies = cookies.split(";");
if (cookies[0] == "" && cookies[0][0] == undefined) {
return undefined;
}
cookies.forEach(function(cookie) {
cookie = cookie.split(/=(.+)/);
if (cookie[0].substr(0, 1) == ' ') {
cookie[0] = cookie[0].substr(1);
}
cookiestore[cookie[0]] = cookie[1];
});
return (name !== '' ? cookiestore[name] : cookiestore);
}
Usage
getcookie() - returns an object with all cookies on the web page.
getcookie('myCookie') - returns the value of the cookie myCookie from the cookie object, otherwise returns undefined if the cookie is empty or not set.
Example
// Have some cookies :-)
document.cookie = "myCookies=delicious";
document.cookie = "myComputer=good";
document.cookie = "myBrowser=RAM hungry";
// Read them
console.log( "My cookies are " + getcookie('myCookie') );
// Outputs: My cookies are delicious
console.log( "My computer is " + getcookie('myComputer') );
// Outputs: My computer is good
console.log( "My browser is " + getcookie('myBrowser') );
// Outputs: My browser is RAM hungry
console.log( getcookie() );
// Outputs: {myCookie: "delicious", myComputer: "good", myBrowser: "RAM hungry"}
// (does cookie exist?)
if (getcookie('hidden_cookie')) {
console.log('Hidden cookie was found!');
} else {
console.log('Still no cookie :-(');
}
// (do any cookies exist?)
if (getcookie()) {
console.log("You've got cookies to eat!");
} else {
console.log('No cookies for today :-(');
}
A functional approach to find existing cookies. It returns an array, so it supports multiple occurrences of the same name. It doesn't support partial key matching, but it's trivial to replace the === in the filter with a regex.
function getCookie(needle) {
return document.cookie.split(';').map(function(cookiestring) {
cs = cookiestring.trim().split('=');
if(cs.length === 2) {
return {'name' : cs[0], 'value' : cs[1]};
} else {
return {'name' : '', 'value' : ''};
}
})
.filter(function(cookieObject) {
return (cookieObject.name === needle);
});
}
Get cookie by name just pass the name of cookie to below function
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}

indexOf() in javascript

Okay so i have started learning javascript from the book Beginning Javascript 5th ed, just confused by a js script
function getCookieValue(name) {
var value = document.cookie;
var cookieStartsAt = value.indexOf(" " + name + "=");
if (cookieStartsAt == -1) {
cookieStartsAt = value.indexOf(name + "=");
}
if (cookieStartsAt == -1) {
value = null;
} else {
cookieStartsAt = value.indexOf("=", cookieStartsAt) + 1;
var cookieEndsAt = value.indexOf(";", cookieStartsAt);
if (cookieEndsAt == -1) {
cookieEndsAt = value.length;
}
value = unescape(value.substring(cookieStartsAt,
cookieEndsAt));
}
return value;}
My question is how does the indexOf operator works here( i know how it works and used it previously) ??
The above program is defined below by the book which goes as :
The first task of the function is to get the document.cookie string and store it in the value variable
var value = document.cookie;
Next, you need to find out where the cookie with the name passed as a parameter to the function
is within the
value string. You use the inde x Of() method of the String object to find this
information, as shown in the following line:
var cookieStartsAt = value.indexOf(" " + name + "=");
The method will return either the character position where the individual cookie is found or ‐1 if no
such name, and therefore no such cookie, exists. You search on
" " + name + "=" so that you don’inadvertently find cookie names or values containing the name that you require. For example, if you
have
xFoo, Foo, and yFoo as cookie names, a search for Foo without a space in front would match
xFoo first, which is not what you want!
What the just just happened here?? How did they achieve the location of the name using indexOf() ?? please explain ? I couldn't understand the xfoo,foo,yfoo example ?? Looking for a simpler example.
document.cookie contains a string like cookiename=cookievalue
indexOf is getting the position of the begining of the value part of the cookie
var cookieStartsAt = value.indexOf("cookiename=");
That allows you to use that number to get the value portion of the string with substring()

RegEx to extract parameters from url hash in JavaScript

My urls will look like:
http://example.com/whatever#page?x=1&locale=hu&y=2
http://example.com/whatever#page?x=1&locale=hu
http://example.com/whatever#page?locale=hu
http://example.com/whatever#page?locale=
http://example.com/whatever#page?x=1
http://example.com/whatever#page
http://example.com/whatever
I'd like to get the locale parameter or empty string if it's not set.
I'm trying something like:
locale = location.hash.replace(/.*(?:[?&]locale=([^&]*))?.*/, "$2");
But my problem is that I couldn't find the right RegExp that works for all cases (both when there's locale= in the hash and when there isn't)
Here's a piece of code that will extract it from the hash and avoid it anywhere else in the URL:
function getLocaleFromHash(url) {
var match = url.match(/#.*[?&]locale=([^&]+)(&|$)/);
return(match ? match[1] : "");
}
And, you can see it work on all your test cases here: http://jsfiddle.net/jfriend00/p37Mx/
If you want to be able to look for any parm in the hash, you would use this:
function getParmFromHash(url, parm) {
var re = new RegExp("#.*[?&]" + parm + "=([^&]+)(&|$)");
var match = url.match(re);
return(match ? match[1] : "");
}
See it work here: http://jsfiddle.net/jfriend00/6kgUk/
A more generic function that will fetch all parameters in the URL would look like this. For normal URLs where the hash is after the query and the parameters are in the query string, it would look like this. This is a bit more code because it does more. It fetches all the parameters into an object where you can look up any parameter by it's key and it URL decodes them all too:
function getParmsFromURL(url) {
var parms = {}, pieces, parts, i;
var hash = url.lastIndexOf("#");
if (hash !== -1) {
// remove hash value
url = url.slice(0, hash);
}
var question = url.lastIndexOf("?");
if (question !== -1) {
url = url.slice(question + 1);
pieces = url.split("&");
for (i = 0; i < pieces.length; i++) {
parts = pieces[i].split("=");
if (parts.length < 2) {
parts.push("");
}
parms[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
}
}
return parms;
}
For a special version that handles parameters in a hash value and after a ? in the hash value like in the OP's question (which isn't the typical case), one could use this:
function getParmsFromURLHash(url) {
var parms = {}, pieces, parts, i;
var hash = url.lastIndexOf("#");
if (hash !== -1) {
// isolate just the hash value
url = url.slice(hash + 1);
}
var question = url.indexOf("?");
if (question !== -1) {
url = url.slice(question + 1);
pieces = url.split("&");
for (i = 0; i < pieces.length; i++) {
parts = pieces[i].split("=");
if (parts.length < 2) {
parts.push("");
}
parms[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
}
}
return parms;
}
Working demo: http://jsfiddle.net/jfriend00/v8cd5/
And, then if you wanted the local option, you'd just do this:
var parms = getParmsFromURL(url);
var locale = parms["locale"];
locale = location.hash.match( /[?&]locale=([^&]*)?/ );
locale = ( locale == null ? "" : locale[1] || "" );
Will do the trick. I don't think the .* are needed, because you do not specify a start or an end of the string.
I tested this regular expression on all your examples and they all worked correctly :)
Edit: sorry, it was invalid in some cases. It is now correct in all cases.
If you really want to do it in one regex:
locale = location.hash.match(/([?&]locale=|^((?![?&]locale=).)+$)([^&]*)/)[3];
It works against all of your examples, though I imagine it's horribly inefficient.

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

What is the shortest, accurate, and cross-browser compatible method for reading a cookie in JavaScript?
Very often, while building stand-alone scripts (where I can't have any outside dependencies), I find myself adding a function for reading cookies, and usually fall-back on the QuirksMode.org readCookie() method (280 bytes, 216 minified.)
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;
}
It does the job, but its ugly, and adds quite a bit of bloat each time.
The method that jQuery.cookie uses something like this (modified, 165 bytes, 125 minified):
function read_cookie(key)
{
var result;
return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? (result[1]) : null;
}
Note this is not a 'Code Golf' competition: I'm legitimately interested in reducing the size of my readCookie function, and in ensuring the solution I have is valid.
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:
https://jsben.ch/AhMN6
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]}
Assumptions
Based on the question, I believe some assumptions / requirements for this function include:
It will be used as a library function, and so meant to be dropped into any codebase;
As such, it will need to work in many different environments, i.e. work with legacy JS code, CMSes of various levels of quality, etc.;
To inter-operate with code written by other people and/or code that you do not control, the function should not make any assumptions on how cookie names or values are encoded. Calling the function with a string "foo:bar[0]" should return a cookie (literally) named "foo:bar[0]";
New cookies may be written and/or existing cookies modified at any point during lifetime of the page.
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.)
Loop-based function
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,'');}
Regular expression-based function
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.
Notes
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.
The following function will allow differentiating between empty strings and undefined cookies. Undefined cookies will correctly return undefined and not an empty string unlike some of the other answers here.
function getCookie(name) {
return (document.cookie.match('(^|;) *'+name+'=([^;]*)')||[])[2];
}
The above worked fine for me on all browsers I checked, but as mentioned by #vanovm in comments, as per the specification the key/value may be surrounded by whitespace. Hence the following is more standard compliant.
function getCookie(name) {
return (document.cookie.match('(?:^|;)\\s*'+name.trim()+'\\s*=\\s*([^;]*?)\\s*(?:;|$)')||[])[1];
}
this in an object that you can read, write, overWrite and delete cookies.
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;
}
};
Here goes.. Cheers!
function getCookie(n) {
let a = `; ${document.cookie}`.match(`;\\s*${n}=([^;]+)`);
return a ? a[1] : '';
}
Note that I made use of ES6's template strings to compose the regex expression.
It's 2022, everything except Internet Explorer supports the URLSearchParams API (^1) and String.prototype.replaceAll API (^2), so we can horribly (ab)use them:
const cookies = new URLSearchParams(document.cookie.replaceAll('&', '%26').replaceAll('; ', '&'));
cookies.get('cookie name'); // returns undefined if not set, string otherwise
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].
To truly remove as much bloat as possible, consider not using a wrapper function at all:
try {
var myCookie = document.cookie.match('(^|;) *myCookie=([^;]*)')[2]
} catch (_) {
// handle missing cookie
}
As long as you're familiar with RegEx, that code is reasonably clean and easy to read.
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 ""
(edit: posted the wrong version first.. and a non-functional one at that. Updated to current, which uses an unparam function that is much like the second example.)
Nice idea in the first example cwolves. I built on both for a fairly compact cookie reading/writing function that works across multiple subdomains. Figured I'd share in case anyone else runs across this thread looking for that.
(function(s){
s.strToObj = function (x,splitter) {
for ( var y = {},p,a = x.split (splitter),L = a.length;L;) {
p = a[ --L].split ('=');
y[p[0]] = p[1]
}
return y
};
s.rwCookie = function (n,v,e) {
var d=document,
c= s.cookies||s.strToObj(d.cookie,'; '),
h=location.hostname,
domain;
if(v){
domain = h.slice(h.lastIndexOf('.',(h.lastIndexOf('.')-1))+1);
d.cookie = n + '=' + (c[n]=v) + (e ? '; expires=' + e : '') + '; domain=.' + domain + '; path=/'
}
return c[n]||c
};
})(some_global_namespace)
If you pass rwCookie nothing, it will get
all cookies into cookie storage
Passed rwCookie a cookie name, it gets that
cookie's value from storage
Passed a cookie value, it writes the cookie and places the value in storage
Expiration defaults to session unless you specify one
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.
Here is the simplest solution using javascript string functions.
document.cookie.substring(document.cookie.indexOf("COOKIE_NAME"),
document.cookie.indexOf(";",
document.cookie.indexOf("COOKIE_NAME"))).
substr(COOKIE_NAME.length);
Just to throw my hat in the race, here's my proposal:
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];
}
The above code generates a dict that stores cookies as key-value pairs (i.e., cookieDict), and afterwards accesses the property name to retrieve the cookie.
This could effectively be expressed as a one-liner, but this is only for the brave:
document.cookie.split(';').map((x)=>x.split('=')).reduce((accum,current) => { accum[current[0]]=current[1]; return accum;}, {})[name]
The absolute best approach would be to generate cookieDict at page load and then throughout the page lifecycle just access individual cookies by calling cookieDict['cookiename'].
This function doesn't work for older browser like chrome > 80.
const getCookieValue = (name) => (
document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)')?.pop() || ''
)
I solved it by using this function instead that returns undefined if the cookie is missing:
function getCookie(name) {
// Add the = sign
name = name + '=';
// Get the decoded cookie
var decodedCookie = decodeURIComponent(document.cookie);
// Get all cookies, split on ; sign
var cookies = decodedCookie.split(';');
// Loop over the cookies
for (var i = 0; i < cookies.length; i++) {
// Define the single cookie, and remove whitespace
var cookie = cookies[i].trim();
// If this cookie has the name of what we are searching
if (cookie.indexOf(name) == 0) {
// Return everything after the cookies name
return cookie.substring(name.length, cookie.length);
}
}
}
Credit: https://daily-dev-tips.com/posts/vanilla-javascript-cookies-%F0%9F%8D%AA/
You can verify if a cookie exists and it has a defined value:
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
It will return null if cookie doesn't exists.
Get the cookie value or undefined if it doesn't exist:
document
.cookie
.split('; ')
.filter(row => row.startsWith('cookie_name='))
.map(c=>c.split('=')[1])[0];
On chromium based browsers you can use the experimental cookieStore api:
await cookieStore.get('cookieName');
Check the Browsersupport before using!

Categories