【问题标题】:Chrome browser is not sending if-modified-since header to serverChrome 浏览器未将 if-modified-since 标头发送到服务器
【发布时间】:2012-01-07 19:19:41
【问题描述】:

服务器将这些标头发送到客户端:

Cache-Control:private
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/html
Date:Sun, 27 Nov 2011 11:10:38 GMT
ETag:"12341234"
Set-Cookie:connect.sid=e1u...7o; path=/; expires=Sun, 27 Nov 2011 11:40:38 GMT; httpOnly
Transfer-Encoding:chunked
last-modified:Sat, 26 Nov 2011 21:42:45 GMT

我希望客户端验证文件在服务器上没有更改,如果它有“304”,则发送“200”。

Firefox 发送:

if-modified-since: Sat, 26 Nov 2011 21:42:45 GMT
if-none-match: "12341234"

为什么刷新页面时 chrome 发送的内容不同?我关注.Net 运行的行为:

context.Response.Cache.SetCacheability(HttpCacheability.ServerAndPrivate)

【问题讨论】:

  • 我不明白“我正在关注 .Net 运行的行为:”。你能编辑一下吗?这个问题对我很重要。
  • 在.Net 中: 之后运行代码所获得的行为是一个问题。查看标签,我试图模仿 node.js 中的行为。
  • 对于所有认为这是客户端问题并对这些答案进行投票的人。请阅读:它与服务器相关,因为我在使用 etag (if-none-match) 发出浏览器请求之后。 etag 是在服务器端创建的,与客户端无关。我需要知道的是从服务器发送到客户端的内容,以使其也发送 chrome 中的 etag 标头。所选答案是唯一正确的答案,因为它告诉服务器也发送if-none-match
  • 即使看起来不是这样,也请注意,如果您直接从地址栏请求图像,Chrome 不会发送“If-Modified-Since”标头。仅当从“img”标签或任何与图像相关的 css 属性请求图像时,才会从缓存中检索图像。

标签: http node.js http-headers cache-control


【解决方案1】:

在昨天花了半天时间后,我找到了导致问题的原因。只要您有按 F12 时弹出的 Chrome 对象检查器/客户端调试器/网络监视器/事物,Chrome 就不会发送缓存请求标头。时期。 (更新:在较新版本的 Chrome 中,有一个复选框“禁用缓存”)。即使您没有打开“网络”选项卡(例如:打开 javascript 控制台),此复选框仍会禁用所有缓存。

这很可悲,因为从客户端对此进行调试要求您打开网络面板以查看正在发送和接收的标头以及返回的代码。如果没有打开网络面板,就无法知道您的内容是否正在从客户端缓存。

如果您深入了解您的服务器访问日志,您会注意到您的服务器在您关闭 Chrome 客户端上的调试窗口的那一刻返回 304(缓存内容)。希望这可以帮助。

Chrome 24.0.1312.57

【讨论】:

  • 开发工具有一个选项“禁用缓存(当开发工具打开时)”,也许你启用了它?点击右下角的“齿轮”图标并检查您的设置。
  • +1(是的,您需要取消选中“禁用缓存(在 DevTools 打开时)”)。
  • 这不是答案,答案与服务器有关。
  • 这个答案是一个很好的线索(它确实导致了解决方案,这在 Neek 的评论中),但不幸的是它是错误的。没有打开 devtools 会阻止标题;它正在检查“禁用缓存”。 @Neek 的评论是真正的答案,他/她应该考虑将其作为答案。
  • 如果我理解正确,答案不能与服务器相关,因为If-Modified-Since 是请求标头。因此,它必须由客户端发送。
【解决方案2】:

我在使用 HTTPS 时找到了此行为的一个答案,我想我会分享我的发现。您没有指定是通过 HTTP 还是 HTTPS 请求。

“规则其实很简单:证书的任何错误都意味着页面不会被缓存。”

https://code.google.com/p/chromium/issues/detail?id=110649

如果您使用的是自签名证书,即使您告诉 Chrome 为其添加例外以便页面加载,该页面中的任何资源都不会被缓存,后续请求也不会有 If-Modified-从头开始。

【讨论】:

  • 这似乎不再正确。我有一个页面,浏览器正在为某些资源发送 if-modified-since 标头,而不为其他资源发送它们。
  • 与之前的评论相反,我确实看到了同样的行为。 If-Modified-Since 不是在我拥有无效证书的环境中发送的,而是在我拥有有效证书时发送的。
  • 谢谢,我也遇到了这个问题。我在开发机器上使用自签名证书测试。作为测试,我暂时信任了证书并开始按照您的预期获得 304。
  • 在优化我们包含的库时注意到了同样的事情。自签名证书或不同域的证书将导致脚本文件根本不缓存。浏览器在请求中不发送 if-modified-since 或 if-none-match 标头。切换到 HTTP 或通过证书的 DNS 到相同的服务器将使浏览器包含这些标头。
  • 为你点赞! 4 年后,this 似乎是正确的答案。在使用自签名/忽略证书的本地环境中工作时,Chrome 永远不会发送 If-None-Match 标头。
【解决方案3】:

根据我的经验,您需要的不仅仅是“私有”缓存控制标头。您需要“Max-Age”或“Expires”来强制 Chrome 使用服务器重新验证内容。

请记住,重新验证只会在这些时间值过去后开始,因此可能需要将它们设置为一个较小的值。

【讨论】:

  • 我试过缓存控制:private,max-age=0。没用……还有其他想法吗?我还添加了 expires 标头,但仍然不行。
  • 其实...应该是 max-age=100000 什么的。几乎让它工作了。让它发送 if-none-match 几次,这样就可以了。谢谢!
  • 我通常将 Max-age 设置为 1 小时,但这完全取决于您更新静态内容的频率。如果不确定,请保持较低的值以确保安全。
  • 你们有没有找到真正的解决方案。我遇到了同样的问题,它时不时地发送它。我可以重新加载页面5次,它是否会发送回来就像随机一样。
  • 是的,正如我所说,这完全是关于添加 Max-Age 或 Expires 标头。您需要具体说明内容何时可能过时,否则浏览器将使用自己的算法,正如您所见,这可能是不可预测的。根据我的经验,当您提供这些额外信息时,您总是可以获得可预测的行为。
【解决方案4】:

另外(https://stackoverflow.com/a/14899869/362780):

F12 > 设置 > 常规 > 禁用缓存(在 DevTools 打开时)-> 取消选中此...

【讨论】:

  • 禁用缓存没有勾选,问题依旧。我正在运行版本 58.0.3029.110(64 位)。
  • 实际打开 DevTools 就足够了。这是 Chrome 中的一种错误。
【解决方案5】:

在缓存方面,浏览器有很多反直觉的行为。您会期望,如果响应包含最后修改日期,浏览器会在重用它之前重新验证它。但是主流浏览器都没有真正做到这一点。

适合您情况的理想设置取决于您希望浏览器何时重新验证,请参见下面的链接。

不仅浏览器的行为与直觉相反,不同的浏览器在相同情况下的行为也不同。例如当用户点击刷新按钮时。

您可以阅读不同的浏览器(Internet Explorer、Edge、Safari、FireFox、Chrome)如何使用不同的缓存指令(Etag、last-modified、must-revalidate、expires、max-age、no-cache、no-商店)https://gertjans.home.xs4all.nl/javascript/cache-control.html

【讨论】:

    【解决方案6】:

    我知道这个问题很老,但仍然...... 我注意到 chrome 会记住您上次进行的刷新。因此,如果您按 ctrl+shift+r(刷新和删除缓存),然后按 ctrl+r(只是刷新),chrome 会继续删除缓存,并且不会在收到的响应中显示 304。有一个解决方法。按 ctrl+shift+r 然后转到地址栏,将其聚焦,然后按 Enter。如果您的 etag 设置正确,并且您的服务器已准备好提供 304,您将在调试器中看到一个新的响应代码 - 304。所以它可以工作。

    【讨论】:

    • 我在多个站点上观察到了这种行为。客户端错误与否,知道有时 cmd+r 可能还不够。
    • 接受的答案将帮助网站无法正常工作,并且不会强迫网站用户做他们不应该做的事情。
    • 我的回答并不能替代已接受的回答:) 这只是一个附加信息。
    • 您可以使用问题正下方的 cmets。阅读不相关的“答案”会让人感到困惑。
    • 1.评论太长了。 2.我有同样的问题,偶然发现了这个答案,在这里找不到解决方案,自己找到了一个,回到这里,并分享了我的解决方案。你无法知道它是否正确!它与上面的答案相同,来自带有 Chrome 缓存的 Qeremy。我只是想为其他有同样问题的可怜的混蛋节省时间。随意删除它。
    猜你喜欢
    • 1970-01-01
    • 2011-01-07
    • 2012-04-19
    • 2018-10-23
    • 2010-09-06
    • 2012-11-01
    • 2018-01-27
    • 1970-01-01
    • 2022-10-31
    相关资源
    最近更新 更多