【问题标题】:Why doesn't Chrome re-validate in-memory cache when doing a "normal reload?"为什么 Chrome 在“正常重新加载”时不重新验证内存缓存?
【发布时间】:2018-01-31 09:56:28
【问题描述】:

首先,我在网上找到了一些资源herehere说的是同一件事:

对于正常/软重新加载,浏览器将重新验证缓存,检查文件是否被修改。

我在 Chrome 上进行了测试。我有一个网页index.html,它在body 的末尾加载了一些javascript 文件。当点击刷新按钮(软/正常)时,我从网络面板看到index.html304 Not Modified,这很好。但是,所有 javascript 文件都加载了from memory cache,状态码为 200。没有重新验证!

然后我尝试修改其中一个 javascript 文件。软重装了吗。你猜怎么着?该文件仍然是从内存缓存中加载的!

为什么 Chrome 会这样做?这不是破坏刷新按钮的目的吗?

Here 是关于 Chrome 内存缓存的更多信息。

【问题讨论】:

  • 您如何提供文件?如果您的服务器正在添加可能是原因的缓存控制标头。我会检查缓存资产的网络选项卡并查看它们的标题。
  • Doesn't that defeat the purpose of the refresh button? 不是这样,否则会破坏硬刷新的目的。
  • @Rob 我一开始链接的资源说,即使缓存没有过期,软重载也会“重新验证”缓存。如果你通过地址栏打开页面,那么如果缓存没有过期,它就不会重新验证缓存。见here。所以缓存控制不应该是原因,对吧?
  • 我个人从不让浏览器控制我的网站缓存需求。对于 javascript 文件,很容易对它们进行版本控制,以最简单的形式,您可以在它们上放置一个查询参数,例如..<script src="/js/boot.js?ver=1"/> 但比这更好的是从您的构建工具中自动生成,我使用 webpack 和我的 url 来做到这一点webpack 对它们进行哈希处理。
  • 如果 html 没有被重新加载/更新,那么用户仍然会得到旧的 javascript 文件,不是吗?

标签: javascript html google-chrome caching


【解决方案1】:

这是 Chrome 浏览器于 2017 年引入的一种相对较新的行为。

浏览器众所周知的行为是在用户刷新页面时(通过使用 CTRL+R 组合或专用刷新按钮)通过发送 If-Modified-SinceIf-None-Match 标头来重新验证缓存的资源。它适用于通过 GET 请求获得的所有资源:样式表、脚本、html 等。这会导致大量 HTTP 请求在大多数情况下以 304 Not Modifiedresponses 结尾。

最受欢迎的网站是那些内容不断变化的网站,因此他们的用户倾向于习惯性地刷新它们以获取最新的新闻、推文、视频和帖子。不难想象每秒有多少不必要的请求,据说最好的请求是从未发出过的请求,Facebook 决定解决这个问题,并要求 Chrome 和 Firefox 一起寻找解决方案。


Chrome 提出了所描述的解决方案。

它不会使每个子资源失效,而是只检查 HTML 文档是否发生了变化。如果没有,则意味着很可能其他所有内容都没有被修改,因此它是从浏览器的缓存中返回的。这在每个资源都有内容寻址的 URL 时效果最佳;例如,URL 包含文件内容的哈希值。用户始终可以通过执行硬刷新来克服这种行为。

Firefox 的解决方案为开发人员提供了更多的控制权,并且它是所有浏览器供应商实施的好方法。那是新的Cache-control 指令:immutable
你可以在这里找到更多信息:https://developer.mozilla.org/pl/docs/Web/HTTP/Headers/Cache-Control#Revalidation_and_reloading


资源:

【讨论】:

    【解决方案2】:

    浏览器缓存比以前的简单 200 和 304 稍微复杂一些,并且注意标头中的服务器端指令,以告诉他们如何处理每个特定站点的缓存。

    我们可以使用各种标头(例如Cache-Control)调整浏览器缓存配置文件,具体设置到期前的时间您可以告诉浏览器使用本地副本而不是请求新的新副本,这些可能非常激进对于您确实不想更改的内容(即公司徽标)。通过做类似Cache-Control: public, max-age=31536000

    此外,您还可以设置Expires 标头,这将使您几乎可以执行与Cache-Control 相同的操作,但控制较少。它只是设置在浏览器认为资产陈旧并重新请求之前经过的时间量。尽管通过重新请求,如果从服务器发回未修改的响应代码,我们仍然可以获得缓存的结果。

    许多 Web 服务器都启用了设置,以允许对某些资产文件(js、图像、css)进行更积极的缓存,但对内容文件的缓存则不那么积极。

    【讨论】:

      猜你喜欢
      • 2017-07-15
      • 2014-03-02
      • 2017-09-13
      • 1970-01-01
      • 1970-01-01
      • 2012-08-20
      • 2020-10-07
      • 2017-07-25
      • 1970-01-01
      相关资源
      最近更新 更多