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

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

问题描述

浏览器什么时候没有向服务器请求文件?

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

换句话说,我有一个JavaScript文件正在服务。它的HTTP响应头有 ETag Cache-Control:public Expires:Tue ,2038年1月19日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:


  • 在任何情况下,规范都不会需要缓存提供缓存的内容版本而不重新验证。有很多地方规范指出缓存绝不能使用缓存的内容来满足请求,但是根本没有它指示它必须这样做或者它必须不重新验证。因此,如果他们愿意,浏览器供应商总是可以自由地重新验证。

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

  • 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.
  • 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:



  • fresh(参见第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.

我运行了一个简单的测试,其中我创建了一个包含< script> 标记指向JS文件,< img> 标记指向图像,< link> 标记指向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:


  • 一个E-Tag标题,

  • 最后修改日期,

  • a Cache-Control:max-age = 172800 header

  • an E-Tag header,
  • a Last-Modified date,
  • a Cache-Control: max-age=172800 header

当然,所有资源都在首页加载时提供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中,如果您通过选择网址栏并按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:


互联网有很多种情况资源管理器需要检查缓存条目是否有效:

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.

Google Mozilla 都有一些关于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天全站免登陆