Cookie 的用途
通常,服务器会使用 HTTP Cookie 的内容来确定不同请求是否来自同一个浏览器/用户,然后酌情发出个性化或通用响应。以下描述了一个基本的用户登录系统:
用户向服务器发送登录凭据,例如通过表单提交。
如果凭据正确,服务器会更新 UI 以指示用户已登录,并返回一个包含会话 ID 的 Cookie,该 Cookie 会记录用户在浏览器上的登录状态。
稍后,用户导航到同一网站上的另一个页面。浏览器会随相应的请求一起发送包含会话 ID 的 Cookie,以表明它仍然认为用户已登录。
服务器检查会话 ID,如果仍然有效,则向用户发送新页面的个性化版本。如果无效,则删除会话 ID,并向用户显示该页面的通用版本(或者显示“拒绝访问”消息并要求重新登录)。
Cookie 主要用于三个目的:
会话管理:用户登录状态、购物车内容、游戏分数或服务器需要记住的任何其他与用户会话相关的详细信息。
个性化:用户偏好,例如显示语言和 UI 主题。
跟踪:记录和分析用户行为。
数据存储
在网络早期没有其他选择时,Cookie 被用于一般客户端数据存储目的。现在推荐使用现代存储 API,例如Web Storage API (localStorage 和 sessionStorage) 和IndexedDB。
它们在设计时就考虑到了存储,从不向服务器发送数据,并且没有使用 Cookie 进行存储的其他缺点:
浏览器通常限制每个域的最大 Cookie 数量(因浏览器而异,通常为数百个)和每个 Cookie 的最大大小(通常为 4KB)。存储 API 可以存储更多数据。
Cookie 会随每个请求发送,因此它们可能会降低性能(例如在缓慢的移动数据连接上),尤其是当您设置了大量 Cookie 时。
注意:要查看存储的 Cookie(以及网页正在使用的其他存储),您可以使用 Firefox 开发者工具中的存储检查器,或 Chrome 开发者工具中的应用程序面板。
创建、移除和更新 Cookie
收到 HTTP 请求后,服务器可以通过响应发送一个或多个Set-Cookie 标头,每个标头都会设置一个单独的 Cookie。Cookie 通过指定一个名称-值对来设置,如下所示:
httpSet-Cookie:
以下 HTTP 响应指示接收浏览器存储一对 Cookie:
httpHTTP/2.0 200 OK
Content-Type: text/html
Set-Cookie: yummy_cookie=chocolate
Set-Cookie: tasty_cookie=strawberry
[page content]
注意:了解如何在各种服务器端语言/框架中使用 Set-Cookie 标头:PHP、Node.js、Python、Ruby on Rails。
发出新请求时,浏览器通常会在Cookie HTTP 标头中将先前存储的当前域的 Cookie 发送回服务器:
httpGET /sample_page.html HTTP/2.0
Host: www.example.org
Cookie: yummy_cookie=chocolate; tasty_cookie=strawberry
删除:定义 Cookie 的生命周期
您可以指定一个过期日期或时间段,在此之后 Cookie 应被删除且不再发送。根据创建 Cookie 时Set-Cookie 标头中设置的属性,它们可以是永久或会话Cookie:
永久 Cookie 在 Expires 属性中指定的日期之后删除
httpSet-Cookie: id=a3fWa; Expires=Thu, 31 Oct 2021 07:28:00 GMT;
或在 Max-Age 属性中指定的期限之后删除
httpSet-Cookie: id=a3fWa; Max-Age=2592000
注意:Expires 的可用时间比 Max-Age 长,但是 Max-Age 更不容易出错,并且在两者都设置时具有优先权。其原理是,当您设置 Expires 日期和时间时,它们是相对于设置 Cookie 的客户端而言的。如果服务器设置为不同的时间,这可能会导致错误。
会话 Cookie——没有 Max-Age 或 Expires 属性的 Cookie——在当前会话结束时删除。浏览器定义“当前会话”何时结束,有些浏览器在重新启动时使用会话恢复。这可能导致会话 Cookie 无限期地持续存在。
注意:如果您的网站对用户进行身份验证,它应该在用户进行身份验证时重新生成并重新发送会话 Cookie,即使是已经存在的 Cookie。这种方法有助于防止会话固定攻击,其中第三方可以重用用户的会话。
要立即删除 Cookie,请使用相同的名称、路径和域(如果已指定)再次设置 Cookie,并将其 Expires 属性设置为过去的日期或将其 Max-Age 属性设置为 0 或负值。这会指示浏览器立即删除 Cookie。例如:
httpSet-Cookie: id=a3fWa; Max-Age=0
您还可以使用Clear-Site-Data 响应头清除与可注册域关联的所有 Cookie。例如,从 https://foo.example.com/ 发送的以下头将清除由 example.com 及其所有子域(例如 all.bar.example.com)发送的所有 Cookie。
httpClear-Site-Data: "cookies"
有一些技术旨在在 Cookie 被删除后重新创建它们。这些被称为“僵尸”Cookie。这些技术违反了用户隐私和控制的原则,可能违反数据隐私法规,并可能使使用它们的网站面临法律责任。
更新 Cookie 值
要通过 HTTP 更新 Cookie,服务器可以发送一个Set-Cookie 标头,其中包含现有 Cookie 的名称和新值。例如:
httpSet-Cookie: id=new-value
您可能希望这样做有几个原因,例如用户更新了他们的偏好设置,并且应用程序希望在客户端数据中反映这些更改(您也可以使用客户端存储机制,例如Web Storage)。
通过 JavaScript 更新 Cookie
在浏览器中,您可以使用Document.cookie 属性或异步Cookie Store API 通过 JavaScript 创建新的 Cookie。请注意,以下所有示例都使用 Document.cookie,因为它是支持最广泛/最成熟的选项。
jsdocument.cookie = "yummy_cookie=chocolate";
document.cookie = "tasty_cookie=strawberry";
您还可以访问现有 Cookie 并为其设置新值:
jsconsole.log(document.cookie);
// logs "yummy_cookie=chocolate; tasty_cookie=strawberry"
document.cookie = "yummy_cookie=blueberry";
console.log(document.cookie);
// logs "tasty_cookie=strawberry; yummy_cookie=blueberry"
出于安全目的,您无法通过在发起请求时直接发送更新的 Cookie 标头来更改 Cookie 值,例如通过fetch() 或XMLHttpRequest。
有一些充分的理由不应该允许 JavaScript 根本修改 Cookie。您可以通过在其创建期间指定HttpOnly 属性来阻止 JavaScript 访问 Cookie。有关更多详细信息,请参阅安全部分。
安全
当您在 Cookie 中存储信息时,默认情况下,所有 Cookie 值对最终用户都是可见的,并且可以由最终用户更改。您真的不希望您的 Cookie 被滥用——例如被不良行为者访问/修改,或发送到不应该发送到的域。潜在的后果可能从令人烦恼的(应用程序无法正常工作或表现出奇怪的行为)到灾难性的。例如,犯罪分子可以窃取会话 ID 并使用它来设置一个 Cookie,使其看起来像是他们以其他人的身份登录,从而控制他们的银行或电子商务账户。
您可以通过多种方式保护您的 Cookie,本节将对此进行回顾。
阻止访问您的 Cookie
您可以通过两种方式确保 Cookie 安全发送且不会被意外方或脚本访问:使用 Secure 属性和 HttpOnly 属性:
httpSet-Cookie: id=a3fWa; Expires=Thu, 21 Oct 2021 07:28:00 GMT; Secure; HttpOnly
带有 Secure 属性的 Cookie 仅通过 HTTPS 协议随加密请求发送到服务器。它绝不会随不安全的 HTTP 发送(除了在 localhost 上),这意味着中间人攻击者无法轻易访问它。不安全的站点(URL 中带有 http:)无法设置带有 Secure 属性的 Cookie。但是,不要假设 Secure 可以阻止对 Cookie 中敏感信息的所有访问。例如,有权访问客户端硬盘(或 JavaScript,如果未设置 HttpOnly 属性)的人可以读取和修改信息。
带有 HttpOnly 属性的 Cookie 无法被 JavaScript 访问,例如使用Document.cookie;它只能在到达服务器时才能访问。例如,持久化用户会话的 Cookie 应该设置 HttpOnly 属性——将它们提供给 JavaScript 会非常不安全。这种预防措施有助于缓解跨站脚本(XSS)攻击。
注意:根据应用程序的不同,您可能希望使用服务器查找的不透明标识符,而不是直接将敏感信息存储在 Cookie 中,或者研究替代的身份验证/保密机制,例如JSON Web Tokens。
定义 Cookie 的发送位置
Domain 和 Path 属性定义了 Cookie 的范围:Cookie 发送到哪些 URL。
Domain 属性指定哪个服务器可以接收 Cookie。如果指定,Cookie 在指定的服务器及其子域上可用。例如,如果您从 mozilla.org 设置 Domain=mozilla.org,则 Cookie 在该域和 developer.mozilla.org 等子域上可用。
httpSet-Cookie: id=a3fWa; Expires=Thu, 21 Oct 2021 07:28:00 GMT; Secure; HttpOnly; Domain=mozilla.org
如果 Set-Cookie 标头未指定 Domain 属性,则 Cookie 在设置它的服务器上可用,但不在其子域上可用。因此,指定 Domain 比省略它限制更少。请注意,服务器只能将其 Domain 属性设置为其自己的域或父域,而不能设置为子域或其他域。因此,例如,域为 foo.example.com 的服务器可以将属性设置为 example.com 或 foo.example.com,但不能设置为 bar.foo.example.com 或 elsewhere.com(Cookie 仍然会发送到子域,例如 bar.foo.example.com)。有关更多详细信息,请参阅无效域。
Path 属性指示请求 URL 中必须存在的 URL 路径,才能发送 Cookie 标头。例如:
httpSet-Cookie: id=a3fWa; Expires=Thu, 21 Oct 2021 07:28:00 GMT; Secure; HttpOnly; Path=/docs
%x2F ("/") 字符被视为目录分隔符,子目录也匹配。例如,如果您设置 Path=/docs,这些请求路径将匹配:
/docs
/docs/
/docs/Web/
/docs/Web/HTTP
但这些请求路径不匹配:
/
/docsets
/en-US/docs
注意:path 属性允许您根据网站的不同部分控制浏览器发送哪些 Cookie。它不作为安全措施,并且不保护免受从不同路径对 Cookie 的未经授权的读取。
使用 SameSite 控制第三方 Cookie
SameSite 属性允许服务器指定是否/何时随跨站点请求发送 Cookie——即第三方 Cookie。跨站点请求是指站点(可注册域)和/或方案(http 或 https)与用户当前访问的站点不匹配的请求。这包括当点击其他网站上的链接导航到您的网站时发送的请求,以及嵌入式第三方内容发送的任何请求。
SameSite 有助于防止信息泄露,保护用户隐私,并提供针对跨站点请求伪造攻击的一些保护。它有三个可能的值:Strict、Lax 和 None:
Strict 导致浏览器仅在响应来自 Cookie 源站点的请求时发送 Cookie。当您的 Cookie 与始终位于初始导航之后的功能(例如身份验证或存储购物车信息)相关时,应该使用此选项。
httpSet-Cookie: cart=110045_77895_53420; SameSite=Strict
注意:用于敏感信息的 Cookie 也应该具有较短的生命周期。
Lax 类似,只是浏览器在用户导航到 Cookie 的源站点时也会发送 Cookie(即使用户来自不同的站点)。这对于影响站点显示的 Cookie 很有用——例如,您可能在您的网站上有一个包含联盟链接的合作伙伴产品信息。当该链接被跟踪到合作伙伴网站时,他们可能希望设置一个 Cookie,说明已跟踪了联盟链接,这将显示奖励横幅并在购买产品时提供折扣。
httpSet-Cookie: affiliate=e4rt45dw; SameSite=Lax
None 指定在源请求和跨站点请求中都发送 Cookie。如果您希望随嵌入在其他站点中的第三方内容(例如广告技术或分析提供商)发出的请求发送 Cookie,这很有用。请注意,如果设置了 SameSite=None,则还必须设置 Secure 属性——SameSite=None 需要安全上下文。
httpSet-Cookie: widget_session=7yjgj57e4n3d; SameSite=None; Secure; HttpOnly
如果没有设置 SameSite 属性,则默认将 Cookie 视为 Lax。
Cookie 前缀
由于 Cookie 机制的设计,服务器无法确认 Cookie 是否从安全来源设置,甚至无法判断 Cookie 最初在何处设置。
子域上的应用程序可以设置具有 Domain 属性的 Cookie,这使得可以在所有其他子域上访问该 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。由于应用程序服务器在确定用户是否已通过身份验证或 CSRF 令牌是否正确时仅检查特定的 Cookie 名称,因此这实际上是针对会话固定的防御措施。
注意:在服务器上,Web 应用程序必须检查包括前缀在内的完整 Cookie 名称。用户代理在请求的Cookie 标头中发送 Cookie 之前不会去除前缀。
有关 Cookie 前缀和浏览器支持当前状态的更多信息,请参阅Set-Cookie 参考文章的前缀部分。
隐私与追踪
早些时候我们讨论了 SameSite 属性如何用于控制何时发送第三方 Cookie,以及这如何有助于保护用户隐私。隐私是构建网站时非常重要的考虑因素,如果做得好,可以与您的用户建立信任。如果做得不好,它可能会完全侵蚀这种信任并导致各种其他问题。
第三方 Cookie 可以由通过
然而,第三方 Cookie 也可能被用来创建令人毛骨悚然、侵入性的用户体验。第三方服务器可以根据同一浏览器在访问多个网站时发送给它的 Cookie 来创建用户浏览历史和习惯的配置文件。典型的例子是,当您在一个网站上搜索产品信息时,无论您走到哪里,都会被类似产品的广告追逐。
浏览器供应商知道用户不喜欢这种行为,因此都已开始默认阻止第三方 Cookie,或者至少计划朝这个方向发展。第三方 Cookie(或仅跟踪 Cookie)也可能被其他浏览器设置或扩展程序阻止。
注意:Cookie 阻止可能导致某些第三方组件(例如社交媒体小部件)无法按预期运行。随着浏览器对第三方 Cookie 施加更多限制,开发人员应该开始寻找减少对它们依赖的方法。
有关第三方 Cookie、与之相关的问题以及可用替代方案的详细信息,请参阅我们的第三方 Cookie 文章。有关隐私的更多信息,请参阅我们的隐私着陆页。
与 Cookie 相关的法规
涵盖 Cookie 使用的法律法规包括:
欧盟的通用数据隐私条例 (GDPR)
欧盟的 ePrivacy 指令
加州消费者隐私法案
这些法规具有全球影响力。它们适用于来自这些司法管辖区(欧盟和加利福尼亚州,但加利福尼亚州的法律仅适用于总收入超过 2500 万美元的实体等)的用户访问的任何万维网站。
这些法规包括以下要求:
通知用户您的网站使用 Cookie。
允许用户选择退出接收部分或全部 Cookie。
允许用户在不接收 Cookie 的情况下使用您的大部分服务。
您所在地区可能还有其他管理 Cookie 使用的法规。您有责任了解并遵守这些法规。有些公司提供“Cookie 横幅”代码,可帮助您遵守这些法规。
注意:公司应披露其网站上使用的 Cookie 类型,以实现透明度并遵守法规。例如,请参阅Google 关于其使用的 Cookie 类型的通知,以及 Mozilla 的网站、通信和 Cookie 隐私通知。
另见
相关 HTTP 标头:Set-Cookie、Cookie
相关 JavaScript API:Document.cookie、Navigator.cookieEnabled、Cookie Store API
第三方 cookie
Cookie 规范:RFC 6265
Cookie、GDPR 和 ePrivacy 指令
帮助改进 MDN
此页面对您有帮助吗?
是
否
了解如何贡献 此页面最后由MDN 贡献者在2025 年 10 月 8 日修改。
在 GitHub 上查看此页面 • 报告此内容的问题