如何在JavaScript中创建和读取cookie的值?
当前回答
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;)
在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);
}
我用这个物体。值是经过编码的,所以在从服务器端读写时必须考虑到这一点。
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
};
})();
简约且功能齐全的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)
}
以下是可以用于创建和检索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 "";
}
推荐文章
- 我如何使用Jest模拟JavaScript的“窗口”对象?
- 我如何等待一个承诺完成之前返回一个函数的变量?
- 在JavaScript中根据键值查找和删除数组中的对象
- 使嵌套JavaScript对象平放/不平放的最快方法
- 如何以及为什么'a'['toUpperCase']()在JavaScript工作?
- 有Grunt生成index.html不同的设置
- 文档之间的区别。addEventListener和window。addEventListener?
- 如何检查动态附加的事件监听器是否存在?
- 如何写setTimeout与参数Coffeescript
- 将JavaScript字符串中的多个空格替换为单个空格
- JavaScript: override alert()
- 重置setTimeout
- 如何确保<select>表单字段被禁用时提交?
- jQuery有不聚焦的方法吗?
- 反应钩子-正确的方式清除超时和间隔