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!
"What ain't tested, ain't working"
The only implementation in the comments that passes most of the tests from jshttp/cookie is the one from @kapouer: https://gist.github.com/rendro/525bbbf85e84fa9042c2?permalink_comment_id=3084097#gistcomment-3084097
So I've fixed the remaining failing tests and refactored a bit the code.
Here the result:
function decode(str: string) {
try {
return decodeURIComponent(str);
} catch {
return str;
}
}
/**
* Parses a `Cookie` HTTP header value or `document.cookie` into an object.
*
* Implementation adapted from https://gist.github.com/rendro/525bbbf85e84fa9042c2?permalink_comment_id=3084097#gistcomment-3084097
*/
export function parseCookie(cookies: string) {
const obj = Object.create(null) as Record<string, string | undefined>;
const list = cookies.split(';');
for (const cookie of list) {
if (cookie === '') continue;
const eq = cookie.indexOf('=');
const key = (eq > 0 ? cookie.slice(0, eq) : cookie).trim();
const value = eq > 0 ? decode(cookie.slice(eq + 1).trim()) : undefined;
if (!(key in obj)) {
obj[key] = value;
}
}
return obj;
}
You can retrieve this implementation + all the tests and benchs in this gist: https://gist.github.com/tkrotoff/a1f83070067300174fbe9f35d0075dd3
@tail-call returns
{"":""}
when cookie is empty. It can crash if str is malformed. It splits uselessly.