-
-
Save rendro/525bbbf85e84fa9042c2 to your computer and use it in GitHub Desktop.
A revision with ES6 syntax.
document.cookie
.split(';')
.reduce((res, c) => {
const [key, val] = c.trim().split('=').map(decodeURIComponent)
try {
return Object.assign(res, { [key]: JSON.parse(val) })
} catch (e) {
return Object.assign(res, { [key]: val })
}
}, {});
and to maintain all number strings as strings (because JSON parses number strings as integers):
document.cookie
.split(';')
.reduce((res, c) => {
const [key, val] = c.trim().split('=').map(decodeURIComponent)
const allNumbers = str => /^\d+$/.test(str);
try {
return Object.assign(res, { [key]: allNumbers(val) ? val : JSON.parse(val) })
} catch (e) {
return Object.assign(res, { [key]: val })
}
}, {});
Only this one works for me
let cookie = document.cookie.split(';').reduce((cookieObject, cookieString) => {
let splitCookie = cookieString.split('=')
try {
cookieObject[splitCookie[0].trim()] = decodeURIComponent(splitCookie[1])
} catch (error) {
cookieObject[splitCookie[0].trim()] = splitCookie[1]
}
return cookieObject
}, [])
Only this one works for me
let cookie = document.cookie.split(';').reduce((cookieObject, cookieString) => { let splitCookie = cookieString.split('=') try { cookieObject[splitCookie[0].trim()] = decodeURIComponent(splitCookie[1]) } catch (error) { cookieObject[splitCookie[0].trim()] = splitCookie[1] } return cookieObject }, [])
you should be passing in an empty object to reduce instead of an array
Succint
Object.fromEntries(document.cookie.split('; ').map(x => x.split('=')))
It's 2019, and I'm surprised that there's no ES6 construct yet to get directly the cookies as a key->value map. And developers are still required to write their own boilerplate utility methods to parse the cookie string.
Succint
Object.fromEntries(document.cookie.split('; ').map(x => x.split('=')))
That's a beauty one-liner but looking at the cookies at stackoverflow even the cookie values might contain =
so based on your solution here's one that takes that into account as well - not a one-liner anymore though but I think my project might just survive with the 3 additional lines
Object.fromEntries(document.cookie.split('; ').map(c => {
const [ key, ...v ] = c.split('=');
return [ key, v.join('=') ];
}));
One nit: split(/; */)
is more robust than split('; ')
@tail-call returns {"":""}
when cookie is empty. It can crash if str is malformed. It splits uselessly.
document.cookie.split(/; */).reduce((obj, str) => {
if (str === "") return obj;
const eq = str.indexOf('=');
const key = eq > 0 ? str.slice(0, eq) : str;
let val = eq > 0 ? str.slice(eq + 1) : null;
if (val != null) try { val = decodeURIComponent(val); } catch(ex) { /* pass */ }
obj[key] = val;
return obj;
}, {});
Don't use, see comment below.
Object.fromEntries(document.cookie.split(/; */).map(cookie => cookie.split('=', 2)))
or with decodeURIComponent
Object.fromEntries(document.cookie.split(/; */).map(c => {
const [ key, v ] = c.split('=', 2);
return [ key, decodeURIComponent(v) ];
}));
Object.fromEntries(document.cookie.split(/; */).map(cookie => cookie.split('=', 2)))or with
decodeURIComponent
Object.fromEntries(document.cookie.split(/; */).map(c => { const [ key, v ] = c.split('=', 2); return [ key, decodeURIComponent(v) ]; }));
That's not going to work because if you specify the limit for the String#split()
then it'll ignore the remaining after the last split.
const array = "a=b=c".split("=", 2);
// array = ["a", "b"];
Cookie values may contain =
as well
@benqus Thanks a lot, I should RTFM. I think I know programming languages where this actually keeps the remaining part but I'm not sure.
.split(/=(.*)$/,2) thats what i did to keep the = at the end
Object.fromEntries(document.cookie.split('; ').map(x => x.split(/=(.*)$/,2).map(decodeURIComponent)))
document.cookie.split("; ").reduce((a,c)=>{let [n,v]=c.split("=");return {...a,[n]:decodeURIComponent(v)};},{})
so these are neat, but does someone have one that's actually been properly tested?
@12Me21 I actually just ran into an issue using the reduce method. Seems that cookies with long values eventually get cut off, leading to obvious issues when you try do something with that value. I've instead opted to use the Object.fromEntries version with no issues so far
I've been using this:
function read_cookies() {
let cookies = {}
for (let item of document.cookie.split(";")) {
let match = item.match(/^\s*([^]*?)="?([^]*?)"?\s*$/)
if (match)
cookies[match[1]] = decodeURIComponent(match[2])
}
return cookies
}
Rewrite to work on older browsers / js versions:
Object.fromEntries(document.cookie.split(/; */).map(function(c) {
var index = c.indexOf("="); // Find the index of the first equal sign
var key = c.slice(0, index); // Everything upto the index is the key
var value = c.slice(index + 1); // Everything after the index is the value
// Return the key and value
return [ decodeURIComponent(key), decodeURIComponent(value) ];
}));
https://stackoverflow.com/a/64472572/8784402
Object.fromEntries(document.cookie.split('; ').map(v=>v.split(/=(.*)/s).map(decodeURIComponent)))
+1, thanks for the helpful code!
This is good but it does mean iterating over the array twice because you're calling
map
and thenreduce
.I refactored this so it will only iterate once with
reduce
.This way, we split the individual cookies by
=
and clean them up inside the reducer and save the extramap
.