了解 Cookie

Cookie 是存储在浏览器中的数据块,用于保留网站执行其功能所需的状态和其他信息。

Cookie 是网站存储在用户计算机上的一个小文件,其中存储的信息会在浏览器和网站之间来回传输。

每个 Cookie 都是一个键值对,以及一些用于控制 Cookie 的使用时间和地点的属性。这些属性用于设置到期日期或指明 Cookie 应仅通过 HTTPS 发送等内容。您可以在 HTTP 标头中或通过 JavaScript 界面设置 Cookie。

Cookie 是向网站添加永久性状态的方法之一。这些功能多年来不断发展演变,但也给该平台留下了一些棘手的旧问题。为解决此问题,浏览器(包括 Chrome、Firefox 和 Edge)正在更改其行为,以强制执行更注重隐私保护的默认设置。

Cookie 的实际应用

假设您有一个博客,想向用户展示“新品动态”宣传信息。用户可以关闭促销信息,之后便不会再看到该信息一段时间。 您可以将该偏好设置存储在 Cookie 中,将其设置为一个月后(260 万秒),然后仅通过 HTTPS 发送。该标题如下所示:

Set-Cookie: promo_shown=1; Max-Age=2600000; Secure
服务器在响应中向浏览器发送三个 Cookie
服务器使用 Set-Cookie 标头设置 Cookie。

当读者查看符合这些要求的网页(他们使用的是安全连接,并且 Cookie 的有效期不超过一个月)时,其浏览器会在请求中发送以下标头:

Cookie: promo_shown=1
在请求中从浏览器发送到服务器的三个 Cookie
浏览器会在 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"
JavaScript 在浏览器中访问 Cookie
JavaScript 可以使用 document.cookie 访问 Cookie。

如果您在一些热门网站上尝试这样做,就会发现大多数网站设置的 Cookie 远远不止 3 个。在大多数情况下,这些 Cookie 会在向该网域发出的每个请求中发送,这会产生一系列影响。上传带宽通常比下载带宽更受限制,因此所有出站请求的开销都会增加首字节时间。请谨慎设置 Cookie 的数量和大小。请使用 Max-Age 属性来帮助确保 Cookie 的保留期限不会超过所需的时间。

什么是第一方 Cookie 和第三方 Cookie?

如果您返回之前查看过的网站,可能会发现其中存在来自多个网域的 Cookie,而不仅仅是您当前访问的网域。与当前网站的网域(即浏览器地址栏中显示的内容)匹配的 Cookie 称为第一方 Cookie。同样,来自当前网站以外网域的 Cookie 称为第三方 Cookie。这不是一个绝对标签,而是与用户的上下文相关;同一 Cookie 可以是第一方 Cookie,也可以是第三方 Cookie,具体取决于用户当时所在的网站。

同一网页上的不同请求向浏览器发送三个 Cookie
网页上的 Cookie 可能来自多个不同的网域。

接着上面的示例,假设您的某篇博文中有一张特别可爱的猫咪照片,该照片托管在 /blog/img/amazing-cat.png 上。由于这张图片非常出色,另一个人直接在其网站上使用了该图片。如果访问者访问过您的博客并拥有 promo_shown Cookie,那么当他们在其他人的网站上查看 amazing-cat.png 时,系统会在请求图片时发送该 Cookie。这对任何人来说都没有特别实用,因为 promo_shown 不会用于此其他用户网站上的任何用途,只会给请求增加开销。

如果这是意外的副作用,您为什么要这样做?正是这种机制让网站能够在第三方环境中使用时保持状态。例如,如果您在自己的网站上嵌入了 YouTube 视频,那么访问者会在播放器中看到“稍后观看”选项。如果访问者已登录 YouTube,则第三方 Cookie 会在嵌入式播放器中提供该会话,这意味着“稍后观看”按钮只会一次性保存视频,而不是提示他们登录,也不必让他们离开您的网页返回 YouTube。

同一 Cookie 在三种不同的环境中发送
在访问不同的网页时,系统会发送第三方环境中的 Cookie。

网络的文化特征之一是,它通常默认处于开放状态。正因如此,很多人得以利用 YouTube 打造自己的内容和应用。不过,这也带来了许多安全和隐私问题。跨站请求伪造 (CSRF) 攻击利用以下事实:Cookie 会附加到对给定来源的任何请求,无论是谁发起的请求。例如,如果您访问 evil.example,则它可能会触发对 your-blog.example 的请求,而您的浏览器会乐意附加关联的 Cookie。如果您的博客不谨慎验证这些请求,则 evil.example 可能会触发删除帖子或添加自己的内容等操作。

用户也越来越了解 Cookie 如何用于跟踪他们在多个网站上的活动。不过,迄今为止还没有一种方法来使用 Cookie 明确声明您的意图。您的 promo_shown Cookie 应仅在第一方环境中发送,而想要嵌入其他网站的 widget 的会话 Cookie 会特意用于提供第三方环境中的登录状态。

您可以通过设置适当的 SameSite 属性,明确说明 Cookie 的用途。

如需识别您的第一方 Cookie 并设置适当的属性,请参阅第一方 Cookie 食谱