Http 如何防止返回304的请求

Http 如何防止返回304的请求,http,caching,http-headers,etag,Http,Caching,Http Headers,Etag,浏览器何时不向服务器请求文件 换句话说,我提供了一个JavaScript文件。它的HTTP响应头有一个ETag,Cache-Control:public,并且Expires:Tue,2038年1月19日03:14:07 GMT 浏览器缓存启动后,服务器返回304 我的问题是,为什么浏览器一开始就要检查服务器并得到304?我不希望浏览器去询问是否有一个新的版本,它应该直接从浏览器缓存加载,而不检查与服务器提供的脚本修改 HTTP响应头的哪种组合可以实现这一点?有一条规则,即在未来将Expires头

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

换句话说,我提供了一个JavaScript文件。它的HTTP响应头有一个
ETag
Cache-Control:public
,并且
Expires:Tue,2038年1月19日03:14:07 GMT

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

我的问题是,为什么浏览器一开始就要检查服务器并得到
304
?我不希望浏览器去询问是否有一个新的版本,它应该直接从浏览器缓存加载,而不检查与服务器提供的脚本修改


HTTP响应头的哪种组合可以实现这一点?

有一条规则,即在未来将Expires头设置为超过一年的会违反规则


因此,此处的HTTP响应头无效(
Expires:Tue,2038年1月19日03:14:07 GMT
)。修复此问题可能会解决问题

过期:
缓存控制:最大年龄=
应该可以工作。您是否在服务器日志中确认浏览器实际上正在进行网络呼叫?例如,我发现firebug有令人困惑的输出,表明您在实际访问缓存时正在进行远程调用

首先,相关的HTTP规范是。如果您查看规范,您将看到两件事:

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

  • 其次,你没有做错什么。浏览器可以自由缓存响应,并根据返回的标题使用这些缓存响应。关键点在于,其中需要注意的是,为缓存响应提供服务的条件之一是响应为:

    • 新鲜(见第4.2节),或

    • 允许陈腐食用(见第4.2.4节),或

    • 成功验证(见第4.3节)

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

因此,如果你想改变浏览器的缓存行为,那就太倒霉了

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

我运行了一个简单的测试,创建了一个HTML页面,其中包含一个指向JS文件的
标记、一个指向图像的
标记和一个指向CSS样式表的
标记。所有这些文件都托管在Apache服务器上,该服务器配置为通过以下方式为它们提供服务:

  • 电子标签标题
  • 最后修改的日期
  • a
    缓存控制:最大年龄=172800
当然,所有资源在第一页加载时都有200个代码。此后,在Chrome或Firefox中使用默认设置进行测试时,我发现:

  • 如果通过F5键或“刷新”按钮刷新页面,则页面和所有资源将重新验证(即,向服务器请求每个资源并返回304)
  • 如果您通过链接返回页面或在新选项卡的URL栏中输入URL,则不会进行重新验证(即,不会提出任何请求)
  • 在Chrome中,如果通过选择URL栏并按Enter键刷新页面,页面本身将重新验证,但其他资源不会重新验证。在Firefox中,页面和资源都不会重新验证
表示Internet Explorer具有相同的行为:

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

  • 缓存的条目没有过期日期,并且内容是在浏览器会话中首次访问的
  • 缓存项有过期日期,但已过期
  • 用户已通过单击刷新按钮或按F5请求页面更新
换句话说,通常只有当用户显式刷新页面时,才会看到这些重新验证请求。除非您对浏览器缓存的行为有一些非常特殊的要求,否则这种行为似乎是完全合理的

他们都有一些关于HTTP缓存的文档(我在MSDN或Apple Developers网站上找不到任何等效的文档),但都没有表明存在任何特定于供应商的缓存头,可以用来修改浏览器用于选择何时重新验证的规则。你想做的事根本不可能


如果您确实需要对这种行为进行更多的控制,您可以使用HTML5本地存储查看或滚动您自己的缓存逻辑,就像这样。

如果您在我的船上,并且在IIS中部署了Angular应用程序,请确保您的web.config配置为正确重写url,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <httpErrors errorMode="Detailed" />
        <rewrite>
            <rules>
                <rule name="Angular Routes" stopProcessing="true">
                    <match url=".*" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="/NameOfYourApp_UnderDefaultWebSite/" />
                </rule>
            </rules>
        </rewrite>
  </system.webServer>
</configuration>

特别注意

塞特是谁