为什么Chrome报告过期的响应标头?

时间:2018-01-28 17:50:04

标签: google-chrome caching http-headers

使用TomCat为网站提供服务。通常,当我更新网站时,Chrome会对缓存感到困惑,并继续在缓存中使用旧页面,即使有更新的页面可用。这似乎是基于一个更基本的问题,即Chrome没有从服务器获取最新的响应标头,这似乎阻止了任何控制缓存的能力。

我选择了一个javascript文件,做了一个小修改来改变文件系统中文件的日期。然后,我在Mozilla和Chrome中重新获取了该页面。 Mozilla似乎运行正常:服务器返回200,最重要的是Last-Modified标头与文件上的时间戳相同。

然而,Chrome,我得到了最好奇的回应。它声称获得200响应,但它不刷新其缓存。根据Chrome的说法,Last-Modified标题来自几个月前!我在非常基本的服务文件模式下使用TomCat - 没有涉及我的特殊代码。我真的不相信TomCat会向Chrome返回不同​​的标题。

看起来Chrome甚至不会问服务器。我无法在服务器上找到该文件请求的任何记录。看起来Chrome只是坐在缓存的文件中,报告了几天前它所做的提取中的旧标题。它没有从服务器请求标头,也没有发送304.它只是不调用服务器。

我从HTTP测试工具进行了第三次获取,该工具报告返回的标头。以这种方式检索的标头与Mozilla报告的标头匹配,但不匹配Chrome报告的标头。 Chrome似乎已经缓存了之前的标题响应,因此不会下载修改后的文件。

甚至ETag标题也不同。 Mozilla和测试工具报告了W /" 464427-1517160284971"但Chrome声称响应包括W /" 464400-1511152262000"的ETag值。我根本不相信服务器返回了这个值。

我一直在努力让用户不得不清除Chrome上的缓存,而这正是真正的问题。有没有什么方法可以在修改页面时强制Chrome刷新缓存而不会破坏每个人的网络性能。

以下是Mozilla Headers

headers reported by Mozilla

以下是Chrome"报道"头

headers reported by Chrome

以下是测试工具标题。

headers reported by HTTP test tool

1 个答案:

答案 0 :(得分:0)

解决方案似乎是将选项must-validate添加到Cache-Control响应标头中。如果没有此标头,并且没有其他特定时间命令来释放缓存文件,Chrome将永久缓存该文件,并且不会返回服务器并检查是否有更新的文件。

默认情况下,Apace TomCat在响应的must-validate标头中不包含Cache-Control。这就是使用TomCat上的默认设置的原因,Chrome将永久缓存文件。这很奇怪,因为它看起来像是获取了文件,但它没有,它报告了几天前检索文件时的HTTP响应(200)。

在TomCat中,向响应添加标头的唯一方法是编写一个在每个请求上执行此操作的类。这是一个合适的课程:

public class HeaderCorrectingFilter implements Filter {

    public void destroy() {
        //nothing to destroy
    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        ((HttpServletResponse) response).setHeader("Cache-Control", "must-revalidate");
    }

    public void init(FilterConfig arg0) throws ServletException {
    }

}

这是WEB.XML中的设置,可以调用它

<filter>
  <filter-name>HeaderCorrectingFilter</filter-name>
  <filter-class>com.example.HeaderCorrectingFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>HeaderCorrectingFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

这是blog post,其中填写了有关如何制作

的详细信息