Set-Cookie 头
Baseline 广泛可用 *
HTTP Set-Cookie
响应头用于从服务器向用户代理发送一个 cookie,以便用户代理以后可以将其发送回服务器。要发送多个 cookie,应在同一个响应中发送多个 Set-Cookie
头。
警告: 浏览器禁止前端 JavaScript 代码访问 Set-Cookie
头,这是 Fetch 规范所要求的,该规范将 Set-Cookie
定义为禁止响应头名称,必须从暴露给前端代码的任何响应中过滤掉。
当 Fetch API 或 XMLHttpRequest API 请求使用 CORS 时,除非请求包含凭据,否则浏览器将忽略服务器响应中存在的 Set-Cookie
头。请访问使用 Fetch API - 包含凭据和 XMLHttpRequest 文章以了解如何包含凭据。
有关更多信息,请参阅使用 HTTP cookie 指南。
语法
Set-Cookie: <cookie-name>=<cookie-value>
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>
Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<number>
Set-Cookie: <cookie-name>=<cookie-value>; Partitioned
Set-Cookie: <cookie-name>=<cookie-value>; Path=<path-value>
Set-Cookie: <cookie-name>=<cookie-value>; Secure
Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Strict
Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Lax
Set-Cookie: <cookie-name>=<cookie-value>; SameSite=None; Secure
// Multiple attributes are also possible, for example:
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly
属性
-
定义 cookie 名称及其值。cookie 定义以名称-值对开始。
<cookie-name>
可以包含除控制字符(ASCII 字符 0 到 31 和 ASCII 字符 127)或分隔符(空格、制表符以及字符:( ) < > @ , ; : \ " / [ ] ? = { }
)之外的任何 US-ASCII 字符。<cookie-value>
可以选择性地用双引号括起来,并包含除控制字符(ASCII 字符 0 到 31 和 ASCII 字符 127)、空格、双引号、逗号、分号和反斜杠之外的任何 US-ASCII 字符。编码:许多实现对 cookie 值执行百分号编码。但是,RFC 规范不要求这样做。百分号编码确实有助于满足
<cookie-value>
允许的字符要求。注意: 某些 cookie 名称包含前缀,这些前缀对支持用户代理中的 cookie 属性施加了特定的限制。有关更多信息,请参阅Cookie 前缀。
Domain=<domain-value>
可选-
定义将发送 cookie 的主机。
只能将当前域设置为值,或更高阶的域,除非它是公共后缀。设置域将使 cookie 对其以及其所有子域都可用。
如果省略,此属性默认为当前文档 URL 的主机,不包括子域。
与早期规范相反,域名中的前导点(
.example.com
)将被忽略。不允许多个主机/域值,但如果指定了域,则始终包含子域。
Expires=<date>
可选-
指示 cookie 的最长生命周期,以 HTTP-date 时间戳表示。有关所需格式,请参阅
Date
。如果未指定,cookie 将成为会话 cookie。会话在客户端关闭时结束,之后会话 cookie 将被删除。
警告: 许多网络浏览器都有一个会话恢复功能,它将保存所有标签并在下次使用浏览器时恢复它们。会话 cookie 也会被恢复,就好像浏览器从未关闭过一样。
Expires
属性由服务器根据其自身的内部时钟设置,这可能与客户端浏览器的时钟不同。Firefox 和基于 Chromium 的浏览器在内部使用一个经过调整的过期(max-age)值,以补偿时钟差异,根据服务器预设的时间存储和过期 cookie。时钟偏差的调整是根据DATE
头的值计算的。请注意,规范解释了如何解析属性,但未指明接收方是否/如何更正该值。 HttpOnly
可选-
禁止 JavaScript 访问 cookie,例如通过
Document.cookie
属性。请注意,使用HttpOnly
创建的 cookie 仍将随 JavaScript 启动的请求发送,例如在调用XMLHttpRequest.send()
或fetch()
时。这可以减轻针对跨站脚本 (XSS) 的攻击。 Max-Age=<number>
可选-
指示 cookie 过期前的秒数。零或负数将立即使 cookie 过期。如果同时设置了
Expires
和Max-Age
,则Max-Age
优先。 Partitioned
可选-
指示 cookie 应使用分区存储。请注意,如果设置了此项,
Secure
指令也必须设置。有关更多详细信息,请参阅 具有独立分区状态的 Cookie (CHIPS)。 Path=<path-value>
可选-
指示请求的 URL 中必须存在的路径,浏览器才会发送
Cookie
头。如果省略,此属性默认为请求 URL 的路径组件。例如,如果通过对
https://example.com/docs/Web/HTTP/index.html
的请求设置了 cookie,则默认路径将是/docs/Web/HTTP/
。正斜杠 (
/
) 字符被解释为目录分隔符,子目录也匹配。例如,对于Path=/docs
,- 请求路径
/docs
、/docs/
、/docs/Web/
和/docs/Web/HTTP
都将匹配。 - 请求路径
/
、/docsets
、/en-US/docs
将不匹配。
注意:
path
属性允许您根据站点的不同部分控制浏览器发送哪些 cookie。它不打算作为安全措施,并且不能防止从不同路径未经授权地读取 cookie。 - 请求路径
SameSite=<samesite-value>
可选-
控制 cookie 是否随跨站请求发送:即,源自与设置 cookie 的站点(包括方案)不同的站点的请求。这提供了一些针对某些跨站攻击的保护,包括跨站请求伪造 (CSRF) 攻击。
可能的属性值是
Strict
-
仅对源自设置 cookie 的同一站点的请求发送 cookie。
Lax
-
仅对源自设置 cookie 的同一站点的请求发送 cookie,以及满足以下两个条件的跨站请求
-
请求是顶级导航:这实质上意味着请求导致浏览器地址栏中显示的 URL 发生变化。
如果未指定
SameSite
,某些浏览器将Lax
用作默认值:请参阅浏览器兼容性以了解详细信息。注意: 当
Lax
作为默认值应用时,将使用更宽松的版本。在此更宽松的版本中,cookie 也包含在POST
请求中,只要它们在请求发出前不超过两分钟设置。 -
None
-
随跨站和同站请求发送 cookie。使用此值时,
Secure
属性也必须设置。
Secure
可选-
指示仅当请求使用
https:
方案(localhost 除外)时才将 cookie 发送到服务器,因此更能抵抗中间人攻击。注意: 不要假设
Secure
可以防止所有对 cookie 中敏感信息(会话密钥、登录详细信息等)的访问。如果未设置HttpOnly
cookie 属性,具有此属性的 cookie 仍然可以通过访问客户端硬盘或通过 JavaScript 进行读取/修改。不安全的站点(
http:
)不能设置具有Secure
属性的 cookie。当由 localhost 设置Secure
属性时,https:
要求将被忽略。
Cookie 前缀
某些 cookie 名称包含前缀,这些前缀对支持用户代理中的 cookie 属性施加了特定的限制。所有 cookie 前缀都以双下划线 (__
) 开头,以破折号 (-
) 结尾。定义了以下前缀
__Secure-
:名称以__Secure-
开头的 cookie 必须由安全页面 (HTTPS) 设置Secure
属性。__Host-
:名称以__Host-
开头的 cookie 必须由安全页面 (HTTPS) 设置Secure
属性。此外,它们不能指定Domain
属性,并且Path
属性必须设置为/
。这保证了此类 cookie 仅发送给设置它们的主机,而不发送给域上的任何其他主机。它还保证它们在主机范围内设置,并且不能被该主机上的任何路径覆盖。这种组合产生了一个尽可能接近将来源视为安全边界的 cookie。__Http-
:名称以__Http-
开头的 cookie 必须由安全页面 (HTTPS) 设置Secure
标志,并且必须设置HttpOnly
属性以证明它们是通过Set-Cookie
头设置的(它们不能通过 JavaScript 功能(例如Document.cookie
或 Cookie Store API)设置或修改)。__Host-Http-
:名称以__Host-Http-
开头的 cookie 必须由安全页面 (HTTPS) 设置Secure
标志,并且必须设置HttpOnly
属性以证明它们是通过Set-Cookie
头设置的。此外,它们还具有与__Host-
前缀 cookie 相同的限制。这种组合产生了一个尽可能接近将来源视为安全边界的 cookie,同时确保开发人员和服务器操作员知道其范围仅限于 HTTP 请求。
警告: 您不能指望在不支持 cookie 前缀的浏览器上获得这些额外的保证;在这种情况下,带前缀的 cookie 将始终被接受。
示例
会话 cookie
会话 cookie 在客户端关闭时移除。如果未指定 Expires
或 Max-Age
属性,则 cookie 是会话 cookie。
Set-Cookie: sessionId=38afes7a8
永久 cookie
永久 cookie 在特定日期 (Expires
) 或特定时间长度 (Max-Age
) 后移除,而不是在客户端关闭时移除。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT
Set-Cookie: id=a3fWa; Max-Age=2592000
无效域
用户代理应该拒绝不包含设置它的服务器的域的 cookie。
如果由托管在 original-company.com
上的服务器设置,以下 cookie 将被拒绝
Set-Cookie: qwerty=219ffwef9w0f; Domain=some-company.co.uk
将拒绝为服务域的子域设置的 cookie。
如果由托管在 example.com
上的服务器设置,以下 cookie 将被拒绝
Set-Cookie: sessionId=e8bb43229de9; Domain=foo.example.com
Cookie 前缀
名称以 __Secure-
或 __Host-
为前缀的 Cookie 只能在安全 (HTTPS) 源设置 Secure
属性时使用。
名称以 __Http-
或 __Host-Http-
为前缀的 Cookie 只能在安全 (HTTPS) 源设置 Secure
属性时使用,并且必须设置 HttpOnly
属性以证明它们是通过 Set-Cookie
标头设置的,而不是通过 JavaScript 在客户端设置的。
此外,带有 __Host-
或 __Host-Http-
前缀的 cookie 必须具有 /
路径(表示主机上的任何路径),并且不得具有 Domain
属性。
// Both accepted when from a secure origin (HTTPS)
Set-Cookie: __Secure-ID=123; Secure; Domain=example.com
Set-Cookie: __Host-ID=123; Secure; Path=/
// Rejected due to missing Secure attribute
Set-Cookie: __Secure-id=1
// Rejected due to the missing Path=/ attribute
Set-Cookie: __Host-id=1; Secure
// Rejected due to setting a Domain
Set-Cookie: __Host-id=1; Secure; Path=/; Domain=example.com
// Only settable via Set-Cookie
Set-Cookie: __Http-ID=123; Secure; Domain=example.com
Set-Cookie: __Host-Http-ID=123; Secure; Path=/
分区 cookie
Set-Cookie: __Host-example=34d8g; SameSite=None; Secure; Path=/; Partitioned;
注意: 分区 cookie 必须使用 Secure
设置。此外,建议在设置分区 cookie 时使用 __Host
或 __Host-Http-
前缀,以使它们绑定到主机名而不是可注册域。
规范
规范 |
---|
HTTP 状态管理机制 # sane-set-cookie |
浏览器兼容性
加载中…
另见
- HTTP cookie
Cookie
Document.cookie
- Samesite cookie 解释 (web.dev 博客)