如何防止返回304的请求

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

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

浏览器caching启动后,服务器返回304

我的问题是,为什么浏览器甚至检查服务器,并得到一个304位置? 我不希望浏览器询问是否有新版本 – 它应该直接从浏览器caching中加载,而不用检查服务器脚本的修改。

什么组合的HTTP响应头完成这个?

首先,相关的HTTP规范是RFC 7234 。 如果你看规范,你会看到两件事情:

  • 在任何情况下,规范都不要求caching提供caching版本的内容,而不需要重新validation。 有很多地方规范指出,caching不得使用caching的内容来满足请求,但根本不会使用caching的内容,而是指定它必须这样做,或者它不能重新validation。 所以浏览器厂商总是可以随时重新validation,如果他们想。
  • 其次,你没有做错任何事情。 浏览器可以自由地caching响应,并使用这些caching的响应给出您正在返回的标题。 关键是在第4节中 ,注意到服务caching响应的条件之一是响应是:

    • 新鲜的(见4.2节)或者

    • 允许服务陈旧(参见第4.2.4节)或

    • 成功validation(见4.3节)。

    由于您正在吐出将来很远的Expires头,并且未来的这一点尚未达成,所以响应是“新鲜的”,因此不需要重新validation。 所以你在做所有的规格说明你应该在你的最后。 (尽pipe使用Cache-Control: max-age=foo是设置caching过期时间比使用Expires:标头更现代的方法。)

所以,如果你想改变浏览器的caching行为,那么你倒霉了。

但是 ,事情可能不会像你想象的那么糟糕。 您可能只会看到一个请求,而且是因为在testing时刷新了浏览器中的页面。 浏览器根据对其请求的触发方式来处理caching的资源。

我运行了一个简单的testing,在该testing中,我创build了一个包含指向JS文件的<script>标记,指向图像的<img>标记和指向CSS样式表的<link>标记的HTML页面。 所有这些文件都被托pipe在一个Apache服务器上,该服务器被configuration为:

  • 电子标签标题,
  • 最后修改date,
  • Cache-Control: max-age=172800

当然,所有的资源都是在首页加载时用200个代码来提供的。 此后,Chrome或Firefox中的testing使用默认设置进行安装,我观察到:

  • 如果通过F5键或刷新button刷新页面,页面和所有资源将重新生效(即向服务器请求每个资源并返回304)。
  • 如果您通过链接返回页面,或者在新选项卡中将URLinput到URL栏中,则不会进行重新validation(即,没有进行任何请求)。
  • 在Chrome中,如果通过selectURL栏并按Enter键来刷新页面,则页面本身将重新validation,但不会有其他资源。 在Firefox中,页面和资源都无法重新validation。

此页面指示Internet Explorer具有相同的行为:

Internet Explorer需要检查caching条目是否有效的情况很多:

  • caching的条目没有到期date,并且在浏览器会话中第一次访问内容
  • caching的条目具有到期date,但已过期
  • 用户通过单击刷新button或按F5请求页面更新

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

Google和Mozilla都有一些关于HTTPcaching的文档(我在MSDN或苹果开发者网站上找不到任何相同的内容),但都没有暗示存在任何供应商特定的caching标头,可以用来修改浏览器使用的规则select何时重新validation。 你想做什么是根本不可能的。

如果您确实需要对此行为进行更多控制,则可以查看HTML5应用程序caching或使用HTML5本地存储滚动您自己的caching逻辑,就像basket.js一样。

Expires:Cache-Control: max-age=应该工作。 您是否在服务器日志中确认浏览器实际上正在进行networking通话? 例如,我发现萤火虫有混淆的输出,表明您正在打高速caching时正在进行远程调用。

有一个规则是将来在超过一年的时间内设置一个Expires头部会违反 HTTP 1.1 RFC 。

所以,这里的HTTP响应头是无效的( Expires: Tue, 19 Jan 2038 03:14:07 GMT )。 解决这个问题可以解决问题!