繁体   English   中英

如何使用 javascript 从 cookie 创建和读取值?

[英]How do I create and read a value from cookie with javascript?

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

以下是可用于创建和检索 cookie 的功能。

function createCookie(name, value, days) {
    var expires;
    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        expires = "; expires=" + date.toGMTString();
    }
    else {
        expires = "";
    }
    document.cookie = name + "=" + value + expires + "; path=/";
}

function getCookie(c_name) {
    if (document.cookie.length > 0) {
        c_start = document.cookie.indexOf(c_name + "=");
        if (c_start != -1) {
            c_start = c_start + c_name.length + 1;
            c_end = document.cookie.indexOf(";", c_start);
            if (c_end == -1) {
                c_end = document.cookie.length;
            }
            return unescape(document.cookie.substring(c_start, c_end));
        }
    }
    return "";
}

简约且功能齐全的 ES6 方法:

const setCookie = (name, value, days = 7, path = '/') => {
  const expires = new Date(Date.now() + days * 864e5).toUTCString()
  document.cookie = name + '=' + encodeURIComponent(value) + '; expires=' + expires + '; path=' + path
}

const getCookie = (name) => {
  return document.cookie.split('; ').reduce((r, v) => {
    const parts = v.split('=')
    return parts[0] === name ? decodeURIComponent(parts[1]) : r
  }, '')
}

const deleteCookie = (name, path) => {
  setCookie(name, '', -1, path)
}

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

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 选项并添加“天数”:

  • path : '/' - 任何绝对路径。 默认值:当前文档位置,
  • domain : 'sub.example.com' - 不能以点开头。 默认值:没有子域的当前主机。
  • 安全:true - 仅通过 https 提供 cookie。 默认值:假。
  • days : 2 - 直到 cookie 过期的天数。 默认值:会话结束。
    设置过期的替代方法:
    • expires : 'Sun, 18 Feb 2018 16:23:42 GMT' - 作为 GMT 字符串的到期日期。
      当前日期可以通过:new Date(Date.now()).toUTCString()
    • 'max-age' : 30 - 与天数相同,但以秒为单位而不是天数。

其他答案使用“expires”而不是“max-age”来支持较旧的 IE 版本。 这种方法需要 ES7,所以无论如何 IE7 都出来了(这没什么大不了的)。

注意: cookie 值支持诸如“=”和“{:}”之类的有趣字符,并且正则表达式处理前导和尾随空格(来自其他库)。
如果您想存储对象,请在使用 JSON.stringify 和 JSON.parse 之前和之后对它们进行编码,编辑上述内容,或添加其他方法。 例如:

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

Mozilla 创建了一个简单的框架,用于读取和写入完全支持 unicode 的 cookie,以及如何使用它的示例。

一旦包含在页面中,您就可以设置 cookie:

docCookies.setItem(name, value);

读取 cookie:

docCookies.getItem(name);

或删除 cookie:

docCookies.removeItem(name);

例如:

// sets a cookie called 'myCookie' with value 'Chocolate Chip'
docCookies.setItem('myCookie', 'Chocolate Chip');

// reads the value of a cookie called 'myCookie' and assigns to variable
var myCookie = docCookies.getItem('myCookie');

// removes the cookie called 'myCookie'
docCookies.removeItem('myCookie');

Mozilla 的 document.cookie 页面上查看更多示例和详细信息。

这个简单的 js 文件的一个版本 在 github 上

我已经多次使用这个线程的接受答案。 这是一段很棒的代码:简单且可用。 但我通常使用babel和 ES6 和模块,所以如果你和我一样,这里是复制代码以便更快地使用 ES6 开发

接受的答案用 ES6 重写为模块:

export const createCookie = ({name, value, days}) => {
  let expires;
  if (days) {
    let date = new Date();
    date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
    expires = '; expires=' + date.toUTCString();
  } else {
    expires = '';
  }
  document.cookie = name + '=' + value + expires + '; path=/';
};

export const getCookie = ({name}) => {
  if (document.cookie.length > 0) {
    let c_start = document.cookie.indexOf(name + '=');
    if (c_start !== -1) {
      c_start = c_start + name.length + 1;
      let c_end = document.cookie.indexOf(';', c_start);
      if (c_end === -1) {
        c_end = document.cookie.length;
      }
      return unescape(document.cookie.substring(c_start, c_end));
    }
  }
  return '';
};

在此之后,您可以简单地将其作为任何模块导入(路径当然可能会有所不同):

import {createCookie, getCookie} from './../helpers/Cookie';

对于那些需要像 {foo: 'bar'} 这样保存对象的人,我分享了我编辑过的@KevinBurke 答案的版本。 我已经添加了 JSON.stringify 和 JSON.parse,仅此而已。

cookie = {

    set: function (name, value, days) {
        if (days) {
            var date = new Date();
            date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
            var expires = "; expires=" + date.toGMTString();
        }
        else
            var expires = "";
        document.cookie = name + "=" + JSON.stringify(value) + expires + "; path=/";
    },

    get : function(name){
        var nameEQ = name + "=",
            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  JSON.parse(c.substring(nameEQ.length,c.length));
        }

        return null;
    }

}

所以,现在你可以做这样的事情:

cookie.set('cookie_key', {foo: 'bar'}, 30);

cookie.get('cookie_key'); // {foo: 'bar'}

cookie.set('cookie_key', 'baz', 30);

cookie.get('cookie_key'); // 'baz'

这是在 JavaScript 中获取、设置和删除 Cookie的代码。

 function getCookie(name) { name = name + "="; var cookies = document.cookie.split(';'); for(var i = 0; i <cookies.length; i++) { var cookie = cookies[i]; while (cookie.charAt(0)==' ') { cookie = cookie.substring(1); } if (cookie.indexOf(name) == 0) { return cookie.substring(name.length,cookie.length); } } return ""; } function setCookie(name, value, expirydays) { var d = new Date(); d.setTime(d.getTime() + (expirydays*24*60*60*1000)); var expires = "expires="+ d.toUTCString(); document.cookie = name + "=" + value + "; " + expires; } function deleteCookie(name){ setCookie(name,"",-1); }

来源:http: //mycodingtricks.com/snippets/javascript/javascript-cookies/

性能基准

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

TL;DR : for...of版本接缝对于现实生活中的 cookie 数据来说是最快的 :)

重要提示:如果path=/和当前页面路径(例如path=/faq )有相同名称的 cookie,则document.cookie可以提供重复的 cookie 名称 但是当前路径的 cookie 将始终是字符串中的第一个,因此在使用此处提供的另一个答案中的reduce()版本时要注意这一点(它返回最后找到的 cookie 而不是第一个)。

固定reduce()版本在我的回答中更进一步。

对于..of 版本:

现实生活中的基准数据集最快(10 个长值 cookie)。 但是性能结果与 vanilla 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;
}

版本索引

在具有短值的 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-loop 版本;)

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,因此对于当前路径(例如path=/faq )和path=/的重复 cookie 名称效果更好。

此版本是所有性能测试中最慢的版本,因此应避免使用恕我直言。

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() 打字稿函数

这也是我使用encodeURIComponentTypeScriptSameSite选项设置 cookie 的函数版本( Firefox 很快就会需要):

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}`;
}

谷歌浏览器 Cookie 存储 API

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

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

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

幸运的是,我们有其他浏览器的cookie-store polyfill 作为npm 包( gitHub ),它只有1.7kB Gzipped ;)

我使用这个对象。 值是编码的,因此在从服务器端读取或写入时需要考虑它。

cookie = (function() {

/**
 * Sets a cookie value. seconds parameter is optional
 */
var set = function(name, value, seconds) {
    var expires = seconds ? '; expires=' + new Date(new Date().getTime() + seconds * 1000).toGMTString() : '';
    document.cookie = name + '=' + encodeURIComponent(value) + expires + '; path=/';
};

var map = function() {
    var map = {};
    var kvs = document.cookie.split('; ');
    for (var i = 0; i < kvs.length; i++) {
        var kv = kvs[i].split('=');
        map[kv[0]] = decodeURIComponent(kv[1]);
    }
    return map;
};

var get = function(name) {
    return map()[name];
};

var remove = function(name) {
    set(name, '', -1);
};

return {
    set: set,
    get: get,
    remove: remove,
    map: map
};

})();

我喜欢这种在现代 JavaScript 中读取 cookie 的单行解决方案:

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

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

我已经使用js-cookie成功了。

<script src="/path/to/js.cookie.js"></script>
<script>
  Cookies.set('foo', 'bar');
  Cookies.get('foo');
</script>

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

用法:

在您的 head 标签中,包含以下代码:

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

或者

<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');

cookie.set(名称,值)

设置一个cookie。

name: cookie name.
value: cookie value.

例子

cookie.set('age', 25);

cookie.get(name[, defaultValue]);

得到一个饼干。

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

cookie.remove(名称);

删除饼干。

 name: cookie name.
例子
cookie.remove( 'age' );

使用示例

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

函数 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);
}

chrome 团队提出了一种与 Cookie Storage API 异步管理 cookie 的新方法(从版本 87 开始在 Google Chrome 中可用): https ://wicg.github.io/cookie-store/

今天已经将它与其他浏览器的 polyfill 一起使用: https ://github.com/mkay581/cookie-store

// load polyfill
import 'cookie-store';

// set a cookie
await cookieStore.set('name', 'value');
// get a cookie
const savedValue = await cookieStore.get('name');

在 ES6 中读取 cookie 的简单方法。

function getCookies() {
    var cookies = {};
    for (let cookie of document.cookie.split('; ')) {
        let [name, value] = cookie.split("=");
        cookies[name] = decodeURIComponent(value);
    }
    console.dir(cookies);
}

使用模板文字的非常短的 ES6 函数。 请注意,您需要自己对值进行编码/解码,但它可以开箱即用,以实现更简单的目的,例如存储版本号。

const getCookie = (cookieName) => {
  return (document.cookie.match(`(^|;) *${cookieName}=([^;]*)`)||[])[2]
}
  
const setCookie = (cookieName, value, days=360, path='/') => {
  let expires = (new Date(Date.now()+ days*86400*1000)).toUTCString();
  document.cookie = `${cookieName}=${value};expires=${expires};path=${path};`
}

const deleteCookie = (cookieName) => {
  document.cookie = `${cookieName}=;expires=Thu, 01 Jan 1970 00:00:01 GMT;path=/;`;
}  

通过类似于sessionStoragelocalStorage的接口:

const cookieStorage = {
  getItem: (key) {
    const cookies = document.cookie.split(';')
      .map(cookie => cookie.split('='))
      .reduce(
        (accumulation, [key, value]) => ({...accumulation, [key.trim()]: value}),
        {}
      )
    
    return cookies[key]
  },
  setItem: (key, value) {
    document.cookie = `${key}=${value}`
  },
}

它的用法cookieStorage.setItem('', '')cookieStorage.getItem('')

readCookie 的改进版本:

function readCookie( name )
{
    var cookieParts = document.cookie.split( ';' )
    ,   i           = 0
    ,   part
    ,   part_data
    ,   value
    ;

    while( part = cookieParts[ i++ ] )
    {
        part_data = part.split( '=' );

        if ( part_data.shift().replace(/\s/, '' ) === name )
        {
            value = part_data.shift();
            break;
        }

    }
    return value;
}

一旦你找到你的 cookie 值并返回它的值,这应该会中断。 在我看来,双拆分非常优雅。

if 条件上的替换是空格修剪,以确保它正确匹配

function setCookie(cname,cvalue,exdays) {
    var d = new Date();
    d.setTime(d.getTime() + (exdays*24*60*60*1000));
    var expires = "expires=" + d.toGMTString();
    document.cookie = cname+"="+cvalue+"; "+expires;
}

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 "";
}

function checkCookie() {
    var user=getCookie("username");
    if (user != "") {
        alert("Welcome again " + user);
    } else {
       user = prompt("Please enter your name:","");
       if (user != "" && user != null) {
           setCookie("username", user, 30);
       }
    }
}

我写了简单的cookieUtils,它有创建cookie、读取cookie和删除cookie三个函数。

var CookieUtils = {
    createCookie: function (name, value, expireTime) {
        expireTime = !!expireTime ? expireTime : (15 * 60 * 1000); // Default 15 min
        var date = new Date();
        date.setTime(date.getTime() + expireTime);
        var expires = "; expires=" + date.toGMTString();
        document.cookie = name + "=" + value + expires + "; path=/";
    },
    getCookie: function (name) {
        var value = "; " + document.cookie;
        var parts = value.split("; " + name + "=");
        if (parts.length == 2) {
            return parts.pop().split(";").shift();
        }
    },
    deleteCookie: function(name) {
        document.cookie = name +'=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
    }
};

这是提到的w3chools的示例。

function setCookie(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 + ";path=/";
}

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 "";
}

一个简单的阅读

var getCookie = function (name) {
    var valueStart = document.cookie.indexOf(name + "=") + name.length + 1;
    var valueEnd = document.cookie.indexOf(";", valueStart); 
    return document.cookie.slice(valueStart, valueEnd)
}

一种厚颜无耻且简单的读取 cookie 的方法可能是:

let username, id; 
eval(document.cookie); 
console.log(username + ", " + id); // John Doe, 123

如果您知道您的 cookie 包含以下内容,则可以使用此选项: username="John Doe"; id=123; username="John Doe"; id=123; . 请注意,字符串需要在 cookie 中使用引号。 可能不是推荐的方式,但适用于测试/学习。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM