如何在JavaScript中创建和读取cookie的值?
当前回答
简约且功能齐全的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)
}
其他回答
对于那些需要保存{foo: 'bar'}这样的对象的人,我分享了我编辑过的@KevinBurke的答案。我添加了JSON。stringify和JSON。解析,仅此而已。
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'
我使用以下函数,这些函数是我从各种来源中找到的最好的函数,并剔除了一些错误或差异。
函数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);
}
我已经使用这个线程的公认答案很多次了。这是一段很棒的代码:简单且可用。但我通常使用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';
性能基准测试
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;)
Mozilla创建了一个简单的框架,用于读取和写入cookie,并提供了完整的unicode支持以及如何使用它的示例。
一旦包含在页面中,您可以设置cookie:
docCookies.setItem(name, value);
读饼干:
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文档中的更多示例和详细信息。饼干页面。
这个简单的js文件的一个版本在github上。
推荐文章
- 使用jQuery以像素为整数填充或边距值
- 检查是否选择了jQuery选项,如果没有选择默认值
- Next.js React应用中没有定义Window
- 如何重置笑话模拟函数调用计数之前,每次测试
- 如何强制一个功能React组件渲染?
- 在javascript中从平面数组构建树数组
- 将Dropzone.js与其他字段集成到现有的HTML表单中
- 如何在AngularJS中观察路由变化?
- JavaScript DOM删除元素
- 将dd-mm-yyyy字符串转换为日期
- Javascript复选框onChange
- Javascript函数前导bang !语法
- 如何在页面上遍历所有DOM元素?
- 在JS/jQuery中触发按键/按键/按键事件?
- 如何每5秒重新加载页面?