Skip to content

Instantly share code, notes, and snippets.

@rendro
Last active January 23, 2025 10:54
Show Gist options
  • Save rendro/525bbbf85e84fa9042c2 to your computer and use it in GitHub Desktop.
Save rendro/525bbbf85e84fa9042c2 to your computer and use it in GitHub Desktop.
Parse document.cookie into object
document.cookie.split(';').map(function(c) {
return c.trim().split('=').map(decodeURIComponent);
}).reduce(function(a, b) {
try {
a[b[0]] = JSON.parse(b[1]);
} catch (e) {
a[b[0]] = b[1];
}
return a;
}, {});
@norwd
Copy link

norwd commented Aug 24, 2022

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) ];
}));

@nkitku
Copy link

nkitku commented Dec 1, 2022

https://stackoverflow.com/a/64472572/8784402

Object.fromEntries(document.cookie.split('; ').map(v=>v.split(/=(.*)/s).map(decodeURIComponent)))

@VillainsRule
Copy link

+1, thanks for the helpful code!

@tkrotoff
Copy link

"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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment