每个 Web 请求都会发送浏览器 cookie 吗?

Posted

技术标签:

【中文标题】每个 Web 请求都会发送浏览器 cookie 吗?【英文标题】:Does every web request send the browser cookies? 【发布时间】:2010-11-23 02:17:30 【问题描述】:

每个网络请求都会发送浏览器的 cookie 吗?

我说的不是页面浏览量,而是对图片、.js 文件等的请求。

更新 如果一个网页有 50 个元素,那就是 50 个请求。为什么它会为每个请求发送相同的 cookie,它不缓存或知道它已经拥有它吗?

【问题讨论】:

我认为在这种情况下缓存是不可能的——我们谈论的是浏览器向服务器发送数据,而不是相反。由于很多原因,您不能确定在用户发送一个请求后服务器“已经拥有它”。可能存在大量不相互通信的服务器;服务器可能根本不希望(或有空间)记住有关先前请求的任何内容——HTTP 应该是无状态的;每个请求都应该独立于其余请求。出于这个原因,cookie(如身份验证凭据)必须随每个请求一起发送。 我在回答的更新中提到了为什么缓存对 cookie 没有意义:***.com/a/1336178/102960 【参考方案1】:

是的,只要请求的 URL 位于 cookie 中定义的相同域和路径中(以及所有其他限制——安全、httponly、未过期等),那么 cookie 将针对每个请求。

【讨论】:

这就是为什么 Google Page Speed 或 Yahoo 的 YSlow 等页面速度工具建议从单独的无 cookie 域提供静态内容的原因。 我在更新的答案中提到了从单独的域提供内容:***.com/a/1336178/102960 当存在从Site1到Site2的HTTP重定向时,浏览器是否发送Site2 Cookies?【参考方案2】:

正如其他人所说,如果 cookie 的主机、路径等限制得到满足,它将被发送 50 次。

但是你也问了为什么:因为 cookie 是 HTTP 特性,而 HTTP 是无状态的。 HTTP 设计为无需服务器在请求之间存储任何状态即可工作。

事实上,服务器并没有可靠的方法来识别哪个用户正在发送给定的请求。单个 Web 代理(以及 IP 地址)后面可能有 1000 个用户。如果不是每个请求都发送 cookie,服务器将无法知道哪个用户正在请求任何资源。

最后,浏览器不知道服务器是否需要 cookie,它只知道服务器指示它为 foo.com 的任何请求发送 cookie,所以它就这样做了。有时图像需要它们(例如,每个用户动态生成),有时不需要,但浏览器无法分辨。

【讨论】:

对于多路复用方案的 HTTP 1.1 是否如此?即,请求被捆绑到单个 TCP 连接中。当然,每个请求都会收到附加的 cookie 副本。但是如果担心大量的传输重复,HTTP 1.1 可以进行优化。虽然我不知道它是否真的... 那么问题就变成了“浏览器打算将cookie附加到哪些请求?”服务器使用 cookie 设置策略,以决定应该将 cookie 发送回哪些域和 URL 路径,但随后它忘记了它。您需要一种方法来指定连接中的某些请求具有 cookie,而其他请求则没有。这在 HTTP/1.1 中绝对不存在,除非在每个请求中明确包含它们。老实说,减少带宽的更好(标准兼容)解决方案是客户端 gzip 内容编码,但目前还没有人支持。 @Ian Clelland:客户端必须发送第一条消息,所以它不知道服务器会发送什么接受编码(如果服务器发送该字段,HTTP/1.1 §14.3 说它是一个请求标头)。问题在于,即使在同一台服务器上,它也可能因 URL 而异,并且会随着时间的推移而变化,因此使其工作并非易事。 @Chris:不,keepalive 只是节省了 TCP 连接设置/拆卸开销,仅此而已。仍然会为每个请求发送完整的标头。但是,流水线(发送多个请求而不等待响应)可以提供很大帮助。 HTTP/1.1 §8.1 给出了详细信息。【参考方案3】:

是的。每个请求都会发送属于同一域的 cookie。它们没有被缓存,因为 HTTP 是无状态的,这意味着每个请求都必须足以让服务器弄清楚如何处理它。假设您的图像只能由某些用户访问;您必须在这 50 个请求中的每一个请求中都发送您的身份验证 cookie,以便服务器知道它收到的请求池中是您,而不是其他人或访客。

话虽如此,考虑到其他响应中提到的其他限制,例如 HTTPS 设置、路径或域,可能不会发送 cookie。尤其是在那里,需要注意的重要一点是:cookie 不会在域之间共享。这有助于减少对静态文件(例如您提到的图像和脚本)的 HTTP 调用的大小。 示例:您在www.***.com 有 4 个 cookie;如果您向www.***.com/images/logo.png 发出请求,所有这 4 个 cookie 都将被发送。 但是,如果您请求 ***.com/images/logo.png(注意子域更改)或 images.***.com/logo.png,则这 4 个 cookie 将不存在 - 但可能与这些域相关的那些会存在。

您可以阅读更多关于 cookie 和图像请求的信息,例如,*** Blog Post。

【讨论】:

【参考方案4】:

没有。并非每个请求都会发送 cookie。这取决于 cookie 配置和客户端-服务器连接。

例如,如果您的 cookie 的 secure 选项设置为 true,则它必须通过安全的 HTTPS 连接传输。意味着当您看到具有 HTTP 协议的网站时,浏览器不会发送这些 cookie,因为安全标志为真。

【讨论】:

【参考方案5】:

3 年过去了

浏览器不发送 cookie 的另一个原因。您可以将crossOrigin 属性添加到<script> 标记,并将值添加到"anonymous"。这将阻止将 cookie 发送到目标服务器。 99.9% 的时间,您的 javascript 是静态文件,并且您不会根据请求的 cookie 生成该 js 代码。如果您有 1KB 的 cookie,并且您的页面上有 200 个资源,那么您的用户正在上传 200KB,这在 3G 上可能需要一些时间并且对结果页面的影响为零。请访问html attribute: crossorigin 以供参考。

【讨论】:

请解释一下。 @Jake 您可以将 crossOrigin 属性添加到您的 【参考方案6】:

Cookie 有一个“路径”属性。如果 "path=/" ,答案是肯定的。

【讨论】:

是的,您可以组织您的站点/应用程序结构,以便所有需要 cookie 的 URL 都为 /app/ 或类似的 - 它可以保留可移植性,而无需单独的子域来消除多余的开销。或者你可以放弃现在无用的谷歌分析。我已经看到饼干头这么久了,我想知道是不是我祖母在编织它们。【参考方案7】:

我知道这是一个旧线程。但我刚刚注意到,如果您添加尾随点,大多数浏览器都不会发送域的 cookie。例如,http://example.com. 不会收到为.example.com 设置的 cookie。另一方面,Apache 将它们视为同一主机。我发现这有助于使跨域跟踪对我包含的外部资源更加困难,但您也可以出于性能原因使用它。请注意,这会阻碍https 证书的验证。我已经使用 browsershots 和我自己的设备进行了一些测试。除了 safari(移动和桌面)之外,该 hack 几乎适用于所有浏览器,它会在请求中包含 cookie。

【讨论】:

它如何“使我包含的外部资源的跨域跟踪更加困难”?您是在谈论 Farcebook Like 和此类小部件 - 我们知道这些小部件会跟踪意外登录用户的浏览情况吗? 是的。这将使它变得更加困难,因为大多数浏览器不会发送 cookie。因此,例如,如果您包含来自 google.com 的内容并且您已登录到 google,则 google 无法链接这两个请求。这并不保证很难,一些浏览器无论如何都会发送 cookie,并且用于识别用户(如 IP 地址)的可靠性较低且使用较少的方法仍然有效。最大的缺点是,你不能使用 HTTPS,这让它在今天毫无用处。【参考方案8】:

简短的回答是肯定的。以下几行来自JS documentation

Cookie 曾经用于一般客户端存储。虽然当它们是在客户端存储数据的唯一方式时这是合法的,但现在建议使用现代存储 API。每次请求都会发送 Cookie,因此它们会降低性能(尤其是对于移动数据连接)。

【讨论】:

以上是关于每个 Web 请求都会发送浏览器 cookie 吗?的主要内容,如果未能解决你的问题,请参考以下文章

web框架--tornado之cookie

我登录并向浏览器发送安全 cookie。现在在 http 页面上,如果我提出请求,它可以发送安全 cookie 吗?

flask路由和视图和cookie

浏览器中的cookie存储

cookiesessionsessionStoragelocalStorage

会话 cookie 可以用于向网络服务器发送许多请求吗