如何防止返回 304 的请求 [英] How to prevent request that returns 304

查看:32
本文介绍了如何防止返回 304 的请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

浏览器何时不向服务器请求文件?

When does a browser NOT make a request to the server for a file?

换句话说,我有一个正在提供的 JavaScript 文件.它的 HTTP 响应头有一个 ETagCache-Control: publicExpires: Tue, 19 Jan 2038 03:14:07 GMT.

In other words, I have a JavaScript file being served. Its HTTP response header has an ETag, Cache-Control: public, and Expires: Tue, 19 Jan 2038 03:14:07 GMT.

浏览器缓存启动后,服务器返回304.

The server is returning a 304 after the browser cache has been primed.

我的问题是,为什么浏览器甚至首先检查服务器并获得 304 ?我不希望浏览器询问是否有新版本——它应该直接从浏览器缓存加载,而不用检查提供脚本的服务器的修改.

My question is, why is the browser even checking with the server and getting a 304 in the first place? I don't want the browser to go ask if there's a new version—it should load directly from browser cache without checking for modifications with the server serving the script.

什么样的 HTTP 响应头组合可以实现这一点?

What combination of HTTP response headers accomplishes this?

推荐答案

首先,相关的 HTTP 规范是 RFC 7234.如果您查看规范,您会发现两件事:

Firstly, the relevant HTTP spec is RFC 7234. If you look at the spec you will observe two things:

  • 规范从不要求,在任何情况下,缓存提供内容的缓存版本而无需重新验证.规范在很多地方都指出缓存不得使用缓存内容来满足请求,但没有任何地方规定它必须这样做或不得重新验证.因此,如果浏览器供应商愿意,他们可以随时进行重新验证.

  • The spec never requires, under any circumstances, that a cache serves a cached version of content without revalidating. There are plenty of places where the spec notes that a cache MUST NOT use cached content to satisfy a request, but none at all where it dictates that it MUST do so or that it MUST NOT revalidate. So browser vendors are always free to revalidate if they want to.

其次,你没有做错任何事.浏览器可以自由地缓存响应,并根据您返回的标头使用这些缓存的响应.关键点在 第 4 节 中,其中注意到一个提供缓存响应的条件之一是响应是:

Secondly, you're doing nothing wrong on your end. Browsers are free to cache responses and use those cached responses given the headers you're returning. The key point is in Section 4, where it is noted that one of the conditions for serving a cached response is that the response is either:

  • 新鲜(见第 4.2 节),或

  • fresh (see Section 4.2), or

允许服务过时(见第 4.2.4 节),或

allowed to be served stale (see Section 4.2.4), or

已成功验证(请参阅第 4.3 节).

successfully validated (see Section 4.3).

由于您吐出的 Expires 标头在未来很远,并且尚未到达未来的那个点,因此响应是新鲜的",因此重新验证不是必需的.所以你正在做规范建议你应该做的一切.(尽管使用 Cache-Control: max-age=foo 是一种比使用 Expires: 标头更现代的设置缓存过期时间的方法.)

Since you're spitting out an Expires header that is far in the future, and that point in the future has not yet been reached, the response is 'fresh', and therefore revalidation is not required. So you're doing everything that the spec suggests you should be on your end. (Although using Cache-Control: max-age=foo is a more modern way of setting cache expiry times than using the Expires: header.)

因此,如果您想更改浏览器的缓存行为,那您就不走运了.

So if you want to change the browsers' caching behaviour, you're out of luck.

然而,事情可能没有你想象的那么糟糕.您可能只会看到一个请求和 304,因为您在测试时刷新浏览器中的页面.浏览器处理缓存资源的方式取决于对它们的请求的触发方式.

However, things might not be as bad as you think. You're probably only be seeing a request and 304 because you're refreshing the page in your browser when testing. Browsers handle cached resources differently depending upon how the request for them was triggered.

我运行了一个简单的测试,其中我创建了一个 HTML 页面,其中包含一个 <script> 标记指向一个 JS 文件,一个 <img> 标记指向到图像,以及指向 CSS 样式表的 标记.所有这些文件都托管在配置为为它们提供服务的 Apache 服务器上:

I ran a simple test in which I created a HTML page that contained a <script> tag pointing to a JS file, an <img> tag pointing to an image, and a <link> tag pointing to a CSS stylesheet. All of these files were hosted on an Apache server configured to serve them with:

  • 一个电子标签标头,
  • 最后修改日期,
  • a Cache-Control: max-age=172800 标头

自然地,所有资源在第一页加载时都带有 200 个代码.此后,在 Chrome 或 Firefox 中使用默认设置进行测试,我观察到:

Naturally, all resources were served with 200 codes on first page load. Thereafter, testing in Chrome or Firefox installs with default settings, I observed that:

  • 如果您通过 F5 键或 Refresh 按钮刷新页面,则页面和所有资源都会重新验证(即发出请求为每个资源发送到服务器并返回 304).
  • 如果您通过链接返回该页面或在新标签中的 URL 栏中输入 URL,则不会重新验证(即不发出任何请求).
  • 在 Chrome 中,如果您通过选择 URL 栏并按 Enter 刷新页面,页面本身会重新验证,但其他资源不会这样做.在 Firefox 中,页面和资源都不会重新验证.
  • If you refresh the page via the F5 key or the Refresh button, the page and all resources revalidate (i.e. a request is made to the server for each resource and a 304 returned).
  • If you return to the page via a link or entering the URL into the URL bar in a new tab, then no revalidation is done (i.e. no requests are made).
  • In Chrome, if you refresh the page by selecting the URL bar and pressing Enter, the page itself revalidates but no other resources do. In Firefox, neither the page nor resources revalidate.

此页面表明 Internet Explorer 具有相同的行为:

This page indicates that Internet Explorer has the same behaviour:

在多种情况下,Internet Explorer 需要检查缓存条目是否有效:

There are a number of situations in which Internet Explorer needs to check whether a cached entry is valid:

  • 缓存条目没有过期日期,并且内容是在浏览器会话中第一次访问
  • 缓存的条目有一个过期日期,但它已经过期
  • 用户通过点击刷新按钮或按 F5 请求更新页面

换句话说,如果用户明确刷新页面,您通常只会看到这些重新验证请求.除非您对浏览器缓存的行为有一些非常特殊的要求,否则这种行为似乎是完全合理的.

In other words, you're usually only going to see these revalidation requests if the user explicitly refreshes the page. Unless you have some very particular requirements about how you want the browser cache to behave, this behaviour seems perfectly reasonable.

GoogleMozilla 都有一些关于 HTTP 缓存的文档(我找不到任何东西等效于 MSDN 或 Apple Developers 站点),但都没有表明存在任何特定于供应商的缓存标头,这些标头可用于修改浏览器用来选择何时重新验证的规则.您想要做的事情根本不可能.

Google and Mozilla both have some documentation about HTTP caching (I can't find anything equivalent on MSDN or the Apple Developers site), but neither suggests the existence of any vendor-specific caching headers that can be used to modify the rules the browser uses to choose when to revalidate. What you want to do is simply not possible.

如果你真的需要更多地控制这种行为,你可以查看 HTML5 应用程序缓存 或使用 HTML5 本地存储滚动您自己的缓存逻辑,例如 basket.js 确实如此.

If you truly need more control over this behaviour, you could look into the HTML5 Application Cache or roll your own caching logic using HTML5 Local Storage, like basket.js does.

这篇关于如何防止返回 304 的请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆