cookie从入门到精通
cookie对于前端初学者,我想一定是比较熟悉而陌生的,因为在学JS的时候,我们从书上了解到cookie,但又无法实战,所以刚开始的时候我们是知道但不会用的。 但是对于有一定经验的人来说,cookie可能就是一个非常简单的东西了。

一、什么是cookie
cookie是由服务器发给客户端的特殊信息,以文本文件的形式存放在客户端,每次请求都会发送给服务器。 cookie主要用于以下三个方面:
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
二、cookie的特点
存储位置:cookie可以由服务器生成和客户端生成,Cookie 存储在客户端(浏览器)中,通常存储在浏览器的 cookie 存储文件中。
cookie大小:cookie的大小一般不能超过4KB,每个域名下,单个 Cookie 的大小不能超过 4KB(实际限制可能会稍有不同),浏览器通常会对每个域名下的 Cookie 数量进行限制,通常是 20 个左右。
同源策略:浏览器只会将 cookie 发送到与当前页面相同的域名上,也就是说,cookie 只能在同一个域名下使用。
跨域请求:如果你从一个域名请求另一个域名的资源(例如,通过 fetch 或 XMLHttpRequest),cookie 不会自动携带,除非你显式设置一些额外的选项。
作用域
- Path:可以通过 path 属性限制该 Cookie 只在指定的路径下有效。
- Domain:通过 domain 属性可以指定该 Cookie 对哪些域名有效,通常用于跨子域的共享 Cookie。
- Secure:如果设置了 Secure 属性,Cookie 只会通过 HTTPS 协议发送,确保数据传输的安全性。
- HttpOnly:如果设置了 HttpOnly 属性,JavaScript 无法访问该 Cookie,从而提高安全性,避免 XSS 攻击获取敏感信息。
生命周期:
- 会话 Cookie:没有 expires 或 max-age 属性的 Cookie,通常称为会话 Cookie,浏览器关闭时会自动删除。
- 持久性 Cookie:有 expires 或 max-age 属性的 Cookie,会在指定的时间到期之前一直保存在客户端,直到被删除或过期。
自动携带:在客户端发起的 HTTP 请求中,如果请求的域名与 Cookie 的 domain 匹配,浏览器会自动将相应的 Cookie 附加到请求头中(Cookie 头部),传递给服务器。
可读性和修改
- 普通 Cookie 的内容是可以被浏览器中的 JavaScript 代码访问和修改的(如果没有设置 HttpOnly)。
- 对于加密的 Cookie,内容是不能直接被读取的,通常通过加密算法来确保数据的隐私性。
安全性
- XSS 攻击:如果 Cookie 没有 HttpOnly 属性,可能会被恶意的 JavaScript 获取。
- CSRF 攻击:未设置 SameSite 属性时,可能会发生跨站请求伪造(CSRF)攻击,攻击者可以利用受害者的身份发起恶意请求。
三、cookie的基本用法
name和valuename:cookie的名称(必需)。value:cookie的值(必需)。
javascriptdocument.cookie = "username=John";expiresexpires设置 cookie 的过期时间。如果不设置,cookie 会在浏览器会话结束时失效(即关闭浏览器时)。- 设置过期时间需要使用 UTC 格式。
- 如果设置了
expires,cookie 会变为持久性 cookie,即使浏览器关闭后也不会丢失。
javascriptdocument.cookie = "username=John; expires=Wed, 21 Oct 2025 07:28:00 GMT";max-age- 与
expires类似,max-age用来设置从当前时间开始,cookie 的有效期(单位是秒)。 max-age比expires更常用,因为它是相对时间(不需要指定 UTC 格式)。
javascriptdocument.cookie = "username=John; max-age=3600"; // 1小时后过期- 与
pathpath用来指定 cookie 的作用路径。只有路径匹配的请求才会携带该 cookie。- 默认情况下,
cookie的作用路径是设置它的页面路径。
javascriptdocument.cookie = "username=John; path=/"; // 对整个网站有效domaindomain设置 cookie 的作用域(即它在哪个域名下有效)。默认情况下,cookie仅对设置它的域名有效。- 如果希望在子域名中也能共享
cookie,可以使用domain参数将cookie设置为跨子域有效。
javascriptdocument.cookie = "username=John; domain=example.com"; // 使该 cookie 对 example.com 和所有子域名有效securesecure表示 cookie 仅通过 HTTPS 协议传输,确保数据安全。- 如果设置了
secure,该 cookie 只能在通过 HTTPS 请求时发送,HTTP 请求将无法携带该 cookie。
javascriptdocument.cookie = "username=John; secure"; // 仅通过 HTTPS 发送SameSiteSameSite用于控制cookie是否在跨站请求时发送。常用于防止 CSRF 攻击。SameSite=Strict: 仅在同源请求中发送 cookie,不会在跨域请求中发送。SameSite=Lax: 允许某些跨域请求(如 GET 请求)携带 cookie,但 POST 等其他请求不会携带。SameSite=None: 允许跨域请求时发送 cookie,但需要同时设置secure,确保 cookie 通过 HTTPS 发送。
javascriptdocument.cookie = "username=John; SameSite=Lax"; // 允许部分跨域请求 document.cookie = "username=John; SameSite=None; Secure"; // 跨域请求时必须使用 HTTPS
结合示例
假设我们要设置一个 cookie,它的名字是 username,值是 John,有效期为 1 小时,作用域为 example.com,并且仅在 HTTPS 请求中发送,且允许跨域请求时携带 cookie。
document.cookie =
"username=John; max-age=3600; path=/; domain=example.com; secure; SameSite=None";总结
expires和max-age用于设置cookie的过期时间或有效期。path和domain控制cookie的作用范围。secure确保cookie仅通过 HTTPS 传输。SameSite控制cookie是否在跨域请求时发送,常用于防止 CSRF 攻击。
这些参数可以灵活使用,确保 cookie 的安全性和有效性。
四、cookie应用场景
保持http会话状态
众所周知HTTP是一个无状态超文本传输协议,session-cookie常用作来保持会话的状态,即用户跟踪用户的状态。

前端会存一个sessionId,后端会存一个sessionId对应的用户信息。
- 当用户登录时,后端会生成一个sessionId,并将其发送给前端,前端会将其存储在本地。
- 当用户访问其他页面时,前端会将sessionId发送给后端,后端会根据sessionId来判断用户是否登录。
- 当用户退出登录时,前端会删除sessionId,后端会删除对应的sessionId。

业务开发中cookie是会经常跨域的,比如www.test.com和game.test.com,这时候就需要用到跨域cookie了。 跨域cookie的实现方式有两种:
- 步骤一:服务器端或客户端设置cookie的domain为父域名,比如www.test.com和game.test.com都设置为test.com
document.cookie = "domain=.test.com; path=/";- 步骤二:前端请求头需要在前端请求中设置 withCredentials。
- 对于fetch api
fetch("https://example.com/data", {
method: "GET",
credentials: "include", // 确保cookie会被发送
});- 对于 XHR (XMLHttpRequest):
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://example.com/data", true);
xhr.withCredentials = true; // 确保cookie会被发送
xhr.send();- 步骤三:服务端设置服务器的 CORS 响应头 服务器也需要显式允许跨域请求携带 cookie。具体的 CORS 响应头需要设置:
Access-Control-Allow-Origin:必须设置为具体的域名(不能是 *),允许跨域请求。 Access-Control-Allow-Credentials:必须设置为 true,才能允许跨域时发送 cookie。 例如,服务器返回的 CORS 响应头:
Access-Control-Allow-Origin: https://game.test.com
Access-Control-Allow-Credentials: true- 步骤四:cookie 的 SameSite 属性(SameSite=None)必须显式设置为允许跨域传递。 SameSite=None:允许跨域传递 cookie。 SameSite=Strict 或 SameSite=Lax:不允许跨域传递 cookie。

cookie换肤和语言功能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>换肤功能示例</title>
<style id="skin-style">
/* 默认皮肤 */
body {
background-color: #fff;
color: #000;
}
.button {
padding: 10px 20px;
margin: 10px;
cursor: pointer;
}
.light-theme {
background-color: #f0f0f0;
color: #000;
}
.dark-theme {
background-color: #333;
color: #fff;
}
</style>
</head>
<body>
<h1>换肤功能</h1>
<button class="button" onclick="setSkin('light')">浅色模式</button>
<button class="button" onclick="setSkin('dark')">深色模式</button>
<script>
// 获取cookie值
function getCookie(name) {
let cookieArr = document.cookie.split(";");
for (let i = 0; i < cookieArr.length; i++) {
let cookie = cookieArr[i].trim();
if (cookie.startsWith(name + "=")) {
return cookie.substring(name.length + 1);
}
}
return "";
}
// 设置cookie
function setCookie(name, value, days) {
let expires = "";
if (days) {
let date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + value + expires + "; path=/";
}
// 设置皮肤
function setSkin(skin) {
// 设置cookie保存皮肤选择
setCookie("skin", skin, 7);
applySkin(skin);
}
// 应用皮肤
function applySkin(skin) {
const styleTag = document.getElementById("skin-style");
if (skin === "light") {
styleTag.innerHTML = `
body {
background-color: #f0f0f0;
color: #000;
}
`;
} else if (skin === "dark") {
styleTag.innerHTML = `
body {
background-color: #333;
color: #fff;
}
`;
}
}
// 页面加载时检查cookie并应用皮肤
window.onload = function () {
let skin = getCookie("skin");
if (skin) {
applySkin(skin);
}
};
</script>
</body>
</html>cookie购物车功能
网上有很多文章这样说,只能说cookie可以实现,但不是最佳的实现方案,有很多的弊端。 理由如下:
- 理由一:数据同步与一致性
- 云端存储:无论用户在哪台设备上登录,购物车中的商品都可以自动同步,保证数据的一致性。
- Cookie 存储:Cookie 只能存储在当前设备和浏览器中,跨设备或跨浏览器无法共享数据。
- 理由二:安全性
- 云端存储:将购物车数据保存在数据库中,可以通过安全的 API 接口进行操作,避免客户端暴露敏感信息如商品信息、用户信息等。
- Cookie 存储:虽然 Cookie 可以加密,但存储的内容容易被客户端访问和篡改,安全性较低,尤其是在存储用户敏感信息时存在一定的风险。
- 理由三: 存储容量
- 云端存储:云端数据库可以存储更复杂的数据,如商品的属性、数量、价格等,同时还可以进行数据关联,存储量也更大。
- Cookie 存储:Cookie 存储大小有限,每个 Cookie 最大 4KB,因此只能存储一些简单的小数据,不适合存储大量商品信息
- 理由四:长期存储
- 云端存储:数据可以持久化存储,即使用户关闭浏览器、清除 Cookie,数据也不会丢失。用户只要重新登录,就可以恢复购物车内容。
- Cookie 存储:Cookie 存储的数据通常是有限的,而且容易受到用户操作的影响,比如用户清除浏览器的 Cookie,购物车数据就会丢失。
- 理由五:可扩展性
- 云端存储:通过后端 API,您可以灵活地对购物车进行各种操作,如添加、删除商品、计算总价、应用优惠券等。这些操作可以通过强大的后端逻辑支持。
- Cookie 存储:Cookie 的操作比较局限,更多是用来标记状态或记录一些基础信息。
参考资料
MDN cookie
浏览器的同源策略
前端安全系列(一):如何防止XSS攻击?
Cookiecookie、session、token、jwt详解与sso基本实现原理
如何保证数据的加密传输