Cookie 是存储在浏览器中的一块数据,用于保留状态以及网站执行其功能所需的其他信息。
Cookie 是网站存储在用户设备上的一个小文件,其存储的信息会在浏览器和网站之间来回传输。
每个 Cookie 都是一个键值对,以及用于控制该 Cookie 使用时间和地点的多项属性。这些属性用于设置失效日期等设置,或用于指示 Cookie 应仅通过 HTTPS 发送。您可以在 HTTP 标头中设置 Cookie,也可以通过 JavaScript 接口设置 Cookie。
Cookie 是可用于向网站添加持久状态的方法之一。多年来,他们的功能在不断发展和发展,但给平台留下了一些容易留下的问题。为了解决这个问题,浏览器(包括 Chrome、Firefox 和 Edge)正在改变其行为,以强制执行更多可保护隐私的默认设置。
Cookie 的实际运用
假设您有一个博客,想要向用户展示“新变化”促销信息。用户可以关闭宣传内容,之后一段时间内将不会再再次显示该宣传内容。 您可以将该偏好设置存储在 Cookie 中,设置为一个月(2,600,000 秒)后过期,并且仅通过 HTTPS 发送。该标头应如下所示:
Set-Cookie: promo_shown=1; Max-Age=2600000; Secure
![在响应中,服务器将三个 Cookie 发送到浏览器](https://web.developers.google.cn/static/articles/understanding-cookies/image/three-cookies-being-sent-1.png?authuser=9&hl=el)
Set-Cookie
标头设置 Cookie。
当读者查看满足这些要求的网页时(他们已采用安全连接,且 Cookie 的存在时间还不到一个月),其浏览器会在请求中发送以下标头:
Cookie: promo_shown=1
![一个请求中将三个 Cookie 从浏览器发送到服务器](https://web.developers.google.cn/static/articles/understanding-cookies/image/three-cookies-being-sent-2.png?authuser=9&hl=el)
Cookie
标头中发回 Cookie。
您还可以使用 document.cookie
在 JavaScript 中添加和读取可用于该网站的 Cookie。为 document.cookie
赋值将创建或替换具有该键的 Cookie。例如,您可以尝试在浏览器的 JavaScript 控制台中执行以下操作:
→ document.cookie = "promo_shown=1; Max-Age=2600000; Secure"
← "promo_shown=1; Max-Age=2600000; Secure"
读取 document.cookie
将输出可在当前上下文中访问的所有 Cookie,各 Cookie 之间用英文分号分隔:
→ document.cookie;
← "promo_shown=1; color_theme=peachpuff; sidebar_loc=left"
![在浏览器中访问 Cookie 的 JavaScript](https://web.developers.google.cn/static/articles/understanding-cookies/image/javascript-accessing-cook-4ae4ebde94edc.png?authuser=9&hl=el)
document.cookie
访问 Cookie。
如果您对选定的一些热门网站进行测试,会发现大多数网站设置的 Cookie 远远超过 3 个。在大多数情况下,这些 Cookie 会在每次发送到该网域的请求时发送,因此会产生诸多影响。对用户来说,上传带宽通常比下载带宽更受限制,因此所有出站请求的开销会增加连接到第一个字节的时间。保守地控制 Cookie 的数量和大小。请使用 Max-Age
属性帮助确保 Cookie 的保留时间不会超过需要的时间。
什么是第一方 Cookie 和第三方 Cookie?
如果您返回到之前查看的同一网站选择,您可能会注意到存在多个网域的 Cookie,而不只是您当前访问的网站。与当前网站的网域(即浏览器地址栏中显示的内容)匹配的 Cookie 称为第一方 Cookie。同样,来自当前网站以外的网域的 Cookie 称为第三方 Cookie。这并非绝对标签,而是与用户所处的环境相关;同一个 Cookie 可能是第一方 Cookie,也可能是第三方 Cookie,具体取决于用户当时所在的网站。
![同一网页上的不同请求向浏览器发送三个 Cookie](https://web.developers.google.cn/static/articles/understanding-cookies/image/three-cookies-being-sent-93367a53e4231.png?authuser=9&hl=el)
继续上面的示例,假设您的一篇博文中包含一只特别神奇的猫咪,图片托管在 /blog/img/amazing-cat.png
上。因为这幅图片太令人惊叹了
所以有人直接在自己的网站上使用了它如果访问者访问过您的博客且具有 promo_shown
Cookie,那么当他们在其他人的网站上查看 amazing-cat.png
时,该 Cookie 会在该图片请求中发送。这对任何人而言都不是特别有用,因为 promo_shown
不用于对方网站上的任何内容,而只是增加了请求的开销。
如果这并非预期效果,您为什么要这么做?正通过这种机制,网站可在第三方上下文中使用时保持状态。例如,如果您在网站上嵌入了 YouTube 视频,访问者就会在播放器中看到“稍后观看”选项。如果您的访问者已登录 YouTube,则该会话可通过第三方 Cookie 在嵌入式播放器中播放,也就是说,“稍后观看”按钮只会一次性保存视频,而不会提示他们登录或必须离开您的网页然后再返回到 YouTube。
![在三种不同的情境下发送同一个 Cookie](https://web.developers.google.cn/static/articles/understanding-cookies/image/the-same-cookie-being-sen-8e25fd5cdbf86.png?authuser=9&hl=el)
网络的文化属性之一是它在默认情况下往往是开放的。正因如此,众多用户能够在 YouTube 上创作出自己的内容和应用。但是,这也带来了许多安全和隐私方面的顾虑。跨站请求伪造 (CSRF) 攻击依赖于 Cookie 附加到向给定来源发送的任何请求这一事实,无论请求由谁发起。例如,如果您访问了 evil.example
,它可以触发对 your-blog.example
的请求,您的浏览器将非常乐意附加关联的 Cookie。如果您的博客不谨慎验证这些请求的方式,evil.example
可能会触发删除帖子或添加自己的内容等操作。
用户也越来越了解可以如何使用 Cookie 在多个网站上跟踪自己的活动。但是,到目前为止,还没有办法使用 Cookie 明确声明您的 intent。promo_shown
Cookie 应仅在第一方环境中发送,而要嵌入到其他网站的 widget 会话 Cookie 则有意用于在第三方环境中提供登录状态。
您可以通过设置适当的 SameSite 属性,使用 Cookie 明确说明您的意图。
要识别您的第一方 Cookie 并设置适当的属性,请参阅第一方 Cookie 使用指南。