在 HTTP
协议中,Cookie
和 Set-Cookie
是两个不同的头部,分别用于发送 Cookie
和 设置 Cookie
。
1. Cookie
(客户端 → 服务器)
- 作用 :客户端(浏览器)在请求中携带已存储的
Cookie
信息,发送给服务器。 - 值的格式 :
-
键值对 :多个
Cookie
以分号和空格分隔。(PS:空格不是必须的) -
示例 :
httpCookie: sessionId=abc123; theme=dark; userId=42
-
解析后的结构 :
javascript{ sessionId: "abc123", theme: "dark", userId: "42" }
-
2. Set-Cookie
(服务器 → 客户端)
Set-Cookie
是一个 HTTP
响应标头用于将 Cookie
由服务器发送到用户代理(即浏览器),以便用户代理在后续的请求中可以将其发送回服务器。要发送多个 Cookie
,则应在同一响应中发送多个 Set-Cookie
标头。)
-
作用 :服务器通过响应头设置新的
Cookie
或更新现有Cookie
。 -
值的格式 :
每个Set-Cookie
头设置一个Cookie
,可包含以下属性(用分号分隔):httpSet-Cookie: <name>=<value>; [Expires=<date>]; [Max-Age=<seconds>]; [Domain=<domain>]; [Path=<path>]; [Secure]; [HttpOnly]; [SameSite=<Strict|Lax|None>]
-
示例 :
httpSet-Cookie: sessionId=abc123; Path=/; Secure; HttpOnly; SameSite=Strict Set-Cookie: theme=dark; Max-Age=3600; Path=/settings
set-cookie 的属性
<cookie-name>=<cookie-value> 必填,其它均可以省略
定义 Cookie
的 name
和 value
。
Domain=<domain-value>
当 Domain
属性被设置为某个域名时,不仅该域名下的请求会携带此 Cookie
,该域名的所有子域名下的请求也会携带此 Cookie
。例如,若设置 Domain=example.com
,则 subdomain.example.com
下的请求同样会携带该 Cookie
.。
同主机的不同端口的 Cookie 会共享,这点和跨域的判断不同
Expires=<date>
以 HTTP
日期时间戳形式指定的 Cookie
的最长有效时间,如果未指定则自动为 会话期Cookie
, 会话期Cookie
在客户端关闭时即删除。
例如:
txt
Set-Cookie: sessionId=abc123; Expires=Sun, 31 Dec 2025 23:59:59 GMT
HttpOnly
设置 HttpOnly
属性后,JavaScript
无法通过 Document.cookie
来访问该 Cookie
,但 Document.cookie
仍会返回其他非 HttpOnly
的 Cookie
。
Max-Age=<number>
在 Cookie
过期之前需要经过的秒数,即有效期。秒数为 0 或负值将会使 Cookie
立刻过期并删除。假如同时设置了 Expires
和 Max-Age
属性,那么 Max-Age
的优先级更高。
Partitioned
用于隔离第三方嵌入的 Cookie
(如 iframe
),避免跨站跟踪。
实验性功能,作用主要是控制 Cookie
是否共享,例如A网站嵌入了C网站页面。B网站也嵌入了C网站页面,之前的两个被嵌入的C网站页面的 Cookie
是共享的,如果开启了这个属性则两个被嵌入的C网站页面,之间不会共享 Cookie
。
Path=<path-value>
表示浏览器要发送该 Cookie
标头时,请求的 URL
中所必须存在的路径。即哪些请求需要带上这个Cookie
。
未指定时默认为发起请求的 Path
。
SameSite=<samesite-value>
控制 Cookie
是否随跨站请求一起发送,这样可以在一定程度上防范跨站请求伪造攻击
Strict
当SameSite
属性设置为Strict
时,浏览器只会在同站请求时发送该Cookie
。也就是说,只有当请求的源(协议、域名和端口)与设置Cookie
的源完全相同时,浏览器才会在请求中携带该Cookie
。跨站请求(例如从另一个网站的链接点击进入当前网站)不会发送SameSite=Strict
的Cookie
。Lax
(默认值 Chrome 80 开始)
SameSite=Lax
是一种相对宽松的策略。在跨站请求中,只有部分安全的顶级导航请求(如通过链接、表单的GET
请求等)会发送该Cookie
,而其他跨站请求(如POST
请求、XMLHttpRequest
、Fetch
请求等)不会发送。在同站请求时,Cookie
会正常发送。None
SameSite=None
表示Cookie
会在同站和跨站请求中都发送,但前提是该Cookie
必须同时设置了Secure
属性,即只能通过HTTPS
协议传输。这是因为在不安全的HTTP
连接下允许跨站发送Cookie
会带来较大的安全风险。
Secure
表示仅当请求通过 https:
协议(localhost
不受此限制)发送时才会将该 Cookie
发送到服务器。
3. 关键区别
特性 | Cookie | Set-Cookie |
---|---|---|
方向 | 客户端 → 服务器 | 服务器 → 客户端 |
内容 | 仅包含键值对 | 键值对 + 控制属性(过期时间、安全标志等) |
数量 | 所有 Cookie 合并为一个头 | 每个 Cookie 对应一个独立的 Set-Cookie 头 |
用途 | 发送已存储的 Cookie | 设置、更新或删除 Cookie |
4. 常见场景示例
场景 1:登录成功设置会话 Cookie
http
HTTP/1.1 200 OK
Set-Cookie: sessionId=abc123; Path=/; HttpOnly; Secure; SameSite=Lax
场景 2:删除 Cookie(设置过期时间为过去)
http
HTTP/1.1 200 OK
Set-Cookie: sessionId=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=/
场景 3:客户端携带 Cookie 请求数据
http
GET /api/data HTTP/1.1
Cookie: sessionId=abc123; theme=dark
5. 示例(Node.js/Express)
设置 Cookie(服务端)
javascript
res.setHeader('Set-Cookie', [
'sessionId=abc123; Path=/; HttpOnly',
'theme=dark; Max-Age=3600'
]);
// 追加
res.appendHeader(
"Set-Cookie",
`${cookieName}=; max-age=0; path=/`
);
读取 Cookie(服务端)
javascript
// 使用 cookie 包解析
const cookie = require('cookie');
const cookies = cookie.parse(req.headers.cookie || '');
console.log(cookies.sessionId); // "abc123"
6. 安全性注意事项
- HttpOnly :防止 JavaScript 通过
document.cookie
访问敏感 Cookie。 - Secure:仅通过 HTTPS 传输 Cookie。
- SameSite :防止跨站请求伪造(CSRF),建议设为
Lax
或Strict
。
总结
Cookie
:客户端发送已存储的键值对。Set-Cookie
:服务器设置包含元数据的单个 Cookie。