如何在JavaScript中创建和读取cookie的值?


当前回答

ES7,使用正则表达式的get()。基于MDN

const Cookie = {
    get: name => {
        let c = document.cookie.match(`(?:(?:^|.*; *)${name} *= *([^;]*).*$)|^.*$`)[1]
        if (c) return decodeURIComponent(c)
    },
    set: (name, value, opts = {}) => {
        /*If options contains days then we're configuring max-age*/
        if (opts.days) {
            opts['max-age'] = opts.days * 60 * 60 * 24;

            /*Deleting days from options to pass remaining opts to cookie settings*/
            delete opts.days 
        }

        /*Configuring options to cookie standard by reducing each property*/
        opts = Object.entries(opts).reduce(
            (accumulatedStr, [k, v]) => `${accumulatedStr}; ${k}=${v}`, ''
        )

        /*Finally, creating the key*/
        document.cookie = name + '=' + encodeURIComponent(value) + opts
    },
    delete: (name, opts) => Cookie.set(name, '', {'max-age': -1, ...opts}) 
    // path & domain must match cookie being deleted 
}

Cookie.set('user', 'Jim', {path: '/', days: 10}) 
// Set the path to top level (instead of page) and expiration to 10 days (instead of session)

用法- Cookie。Get (name, value [, options]): Options支持所有标准cookie选项,并增加了“days”:

path: '/' - any absolute path. Default: current document location, domain: 'sub.example.com' - may not start with dot. Default: current host without subdomain. secure: true - Only serve cookie over https. Default: false. days: 2 - days till cookie expires. Default: End of session. Alternative ways of setting expiration: expires: 'Sun, 18 Feb 2018 16:23:42 GMT' - date of expiry as a GMT string. Current date can be gotten with: new Date(Date.now()).toUTCString() 'max-age': 30 - same as days, but in seconds instead of days.

其他答案使用“expires”而不是“max-age”来支持旧的IE版本。这个方法需要ES7,所以IE7已经出来了(这不是什么大问题)。

注意:像“=”和“{:}”这样有趣的字符被支持作为cookie值,regex处理开头和结尾的空白(来自其他库)。 如果您想存储对象,可以在和JSON之前或之后对它们进行编码。stringify和JSON。解析、编辑上面的内容,或者添加另一个方法。例如:

Cookie.getJSON = name => JSON.parse(Cookie.get(name))
Cookie.setJSON = (name, value, opts) => Cookie.set(name, JSON.stringify(value), opts);

其他回答

我使用以下函数,这些函数是我从各种来源中找到的最好的函数,并剔除了一些错误或差异。

函数setCookie没有高级选项,只有简单的东西,但代码很容易理解,这总是一个优点:

function setCookie(name, value, daysToLive = 3650) { // 10 years default
  let cookie = name + "=" + encodeURIComponent(value);
  if (typeof daysToLive === "number") {
    cookie += "; max-age=" + (daysToLive * 24 * 60 * 60);
    document.cookie = cookie + ";path=/";
  }
}
function getCookie(name) {
  let cookieArr = document.cookie.split(";");
  for (let i = 0; i < cookieArr.length; i++) {
    let cookiePair = cookieArr[i].split("=");
    if (name == cookiePair[0].trim()) {
      return decodeURIComponent(cookiePair[1].trim());
    }
  }
  return undefined;
}
function deleteCookie(name) {
  setCookie(name, '', -1);
}

对于读取简单的查询字符串,这一行代码可能在最新版本的JavaScript中适用:

let cookies = Object.fromEntries(document.cookie.split(';').map(i=>i.trim().split('=')));

现在你有了一个带有键和值的JavaScript对象。

对于创建,你可以试试这个:

let cookieObject = {foo: 'bar', ping: "pong"}
Object.entries(cookieObject).map((e)=>`${e[0]}=${e[1]}`).join(';')

JQuery cookie

或纯Javascript:

function setCookie(c_name,value,exdays)
{
   var exdate=new Date();
   exdate.setDate(exdate.getDate() + exdays);
   var c_value=escape(value) + ((exdays==null) ? "" : ("; expires="+exdate.toUTCString()));
   document.cookie=c_name + "=" + c_value;
}

function getCookie(c_name)
{
   var i,x,y,ARRcookies=document.cookie.split(";");
   for (i=0; i<ARRcookies.length; i++)
   {
      x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("="));
      y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1);
      x=x.replace(/^\s+|\s+$/g,"");
      if (x==c_name)
      {
        return unescape(y);
      }
   }
}

性能基准测试

ES6版本的一些流行getCookie函数的比较(我的改进): https://www.measurethat.net/Benchmarks/Show/16012/5/getcookie-for-vs-forof-vs-indexof-vs-find-vs-reduce

TL;博士:……版本接缝为现实生活中的cookie数据最快:)

重要的是:文档。如果path=/和当前页面路径有相同名称的Cookie, Cookie可以提供重复的Cookie名称。路径= /常见问题解答)。但是当前路径的cookie总是字符串中的第一个,所以在使用这里提供的其他答案的reduce()版本时要注意这一点(它返回最后找到的cookie而不是第一个)。 固定减少()版本是进一步在我的答案。

. .的版本:

对于实际基准测试数据集(10个具有长值的cookie)来说是最快的。但是性能结果与普通for循环和Array.find()几乎相同,所以使用你喜欢的:)

function getCookieForOf(name) {
  const nameEQ = name + '=';
  for (const cookie of document.cookie.split('; ')) {
    if (cookie.indexOf(nameEQ) === 0) {
      const value = cookie.substring(nameEQ.length);
      return decodeURIComponent(value); // returns first found cookie
    }
  }
  return null;
}

IndexOf版本

在1000个具有短值的cookie的人工测试集中,速度非常快(因为它没有创建具有1000个记录的数组)。老实说,我认为在测试代码中可能有一个错误,使得这个版本如此疯狂的快(如果你会发现一些,请告诉我)。无论如何,在真实的应用程序中不太可能有1000个cookie;)

对于具有10个长cookie的真实测试数据集来说,它很慢。

function getCookieIndexOf(name) {
  const nameEQ = name + '=';
  const cookies = document.cookie;
  const cookieStart = cookies.indexOf(nameEQ);
  if (cookieStart !== -1) {
    const cookieValueStart = cookieStart + nameEQ.length;
    const cookieEnd = cookies.indexOf(';', cookieValueStart);
    const value = cookies.substring(
      cookieValueStart,
      cookieEnd !== -1 ? cookieEnd : undefined
    );
    return decodeURIComponent(value); // returns first found cookie
  }
  return null;
}

Array.find()版本

function getCookieFind(name) {
  const nameEQ = name + '=';
  const foundCookie = document.cookie
    .split('; ')
    .find(c => c.indexOf(nameEQ) === 0); // returns first found cookie
  if (foundCookie) {
    return decodeURIComponent(foundCookie.substring(nameEQ.length));
  }
  return null;
}

香草,老派,for循环版本;)

function getCookieFor(name) {
    const nameEQ = name + "=";
    const ca = cookies.split('; ');
    for(let i=0; i < ca.length; i++) {
        const c = ca[i];
        if (c.indexOf(nameEQ) === 0) {
          const value = c.substring(nameEQ.length);
          return decodeURIComponent(value); // returns first found cookie
        }
    }
    return null;
}

// ES5 version:
function getCookieFor(name) {
    var nameEQ = name + "=";
    var ca = cookies.split('; ');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        if (c.indexOf(nameEQ) === 0) {
          var value = c.substring(nameEQ.length);
          return decodeURIComponent(value); // returns first found cookie
        }
    }
    return null;
}

Array.reduce()版本

我的这个答案从@artnikpro的固定版本-返回第一个找到的cookie,所以工作更好的重复cookie名称为当前路径(例如path=/faq)和path=/。

这个版本是所有性能测试中最慢的版本,因此应该避免使用。

function getCookieReduce(name) {
  return document.cookie.split('; ').reduce((r, v) => {
    const [n, ...val] = v.split('='); // cookie value can contain "="
    if(r) return r; // returns first found cookie
    return n === name ? decodeURIComponent(val.join('=')) : r; // returns last found cookie (overwrites)
  }, '');
}

您可以在这里自己运行基准测试:https://www.measurethat.net/Benchmarks/Show/16012/5/getcookie-for-vs-forof-vs-indexof-vs-find-vs-reduce


setCookie() TypeScript函数

下面是我使用encodeURIComponent、TypeScript和SameSite选项(Firefox很快就会需要这些选项)设置cookie的函数版本:

function setCookie(
  name: string,
  value: string = '',
  days: number | false = false, // session length if not provided
  path: string = '/', // provide an empty string '' to set for current path (managed by a browser)
  sameSite: 'none' | 'lax' | 'strict' = 'lax', // required by Firefox
  isSecure?: boolean
) {
  let expires = '';
  if (days) {
    const date = new Date(
      Date.now() + days * 24 * 60 * 60 * 1000
    ).toUTCString();
    expires = '; expires=' + date;
  }
  const secure = isSecure || sameSite === 'none' ? `; Secure` : '';
  const encodedValue = encodeURIComponent(value);
  document.cookie = `${name}=${encodedValue}${expires}; path=${path}; SameSite=${sameSite}${secure}`;
}

谷歌Chrome Cookie存储API

感谢@oncode的回答,值得一提的是谷歌Chrome团队已经提出了一些标准化(终于!这真的很可笑,我们仍然没有任何普遍接受的Cookie API)与异步Cookie存储API(可在谷歌Chrome从版本87开始):https://wicg.github.io/cookie-store/

不幸的是,它仍然是非官方的,甚至不在W3C的考虑范围内,也不在ES的提案范围内:github.com/tc39/proposals

真遗憾,我们仍然没有任何标准的cookie API…

幸运的是,我们为其他浏览器提供了cookie存储polyfill,如npm package (gitHub),它只有1.7kB gzip;)

你可以使用我的cookie ES模块获取/设置/删除cookie。

用法:

在你的head标签中,包括以下代码:

<script src="https://raw.githack.com/anhr/cookieNodeJS/master/build/cookie.js"></script>

or

<script src="https://raw.githack.com/anhr/cookieNodeJS/master/build/cookie.min.js"></script>

现在你可以使用window了。Cookie用于在网页中存储用户信息。

cookie.isEnabled ()

您的网络浏览器是否启用了cookie ?

returns {boolean} true if cookie enabled.

例子

if ( cookie.isEnabled() )
    console.log('cookie is enabled on your browser');
else
    console.error('cookie is disabled on your browser');

饼干。集合(名称,值)

设置一个饼干。

name: cookie name.
value: cookie value.

例子

cookie.set('age', 25);

饼干。get(name[, defaultValue]);

吃块饼干。

name: cookie name.
defaultValue: cookie default value. Default is undefined.
returns cookie value or defaultValue if cookie was not found
Example
var age = cookie.get('age', 25);

饼干。移除(名称);

删除cookie。

name: cookie name.
Example
cookie.remove( 'age' );

用法示例