【问题标题】:Force Cache-Control: no-cache in Chrome via XMLHttpRequest on F5 reload强制缓存控制:在 F5 重新加载时通过 XMLHttpRequest 在 Chrome 中无缓存
【发布时间】:2014-03-12 15:21:20
【问题描述】:

我想确保我通过 AJAX 调用请求的数据是新鲜的并且没有被缓存。因此我发送标题Cache-Control: no-cache

但如果用户按 F5,我的 Chrome 版本 33 会使用 Cache-Control: max-age=0 覆盖此标头。

示例。将test.html 与内容放在您的网络服务器上

<script>
    var xhr = new XMLHttpRequest;
    xhr.open('GET', 'test.html');
    xhr.setRequestHeader('Cache-Control', 'no-cache');
    xhr.send();
</script>

在网络选项卡上的 chrome 调试器中,我看到了 test.html AJAX 调用。状态码 200。现在按 F5 重新加载页面。有 max-age: 0 和状态码 304 Not Modified。

Firefox 显示出类似的行为。不仅仅是覆盖请求标头,而是将其修改为 Cache-Control: no-cache, max-age=0 on F5。

我可以压制这个吗?

【问题讨论】:

  • 另一种解决方案(如果可能)是使用“POST”http 请求,因为浏览器从不缓存 post 请求。

标签: javascript ajax google-chrome caching


【解决方案1】:

另一种方法是将唯一编号附加到 url。

<script>
    var xhr = new XMLHttpRequest;
    xhr.open('GET', 'test.html?_=' + new Date().getTime());
    //xhr.setRequestHeader('Cache-Control', 'no-cache');
    xhr.send();
</script>

时间戳不是很独特,但对于您的用例来说应该足够独特。

【讨论】:

  • @wadim 所以 Chrome 和 Firefox 不遵守 RFC 2616(现在是 7234)?
  • 只是一个注释,这个答案是一个社区维基,所以如果你觉得它不能充分回答这个问题,请随时更新它。我没有时间 atm 重新访问它。
  • 在某些情况下,对相同 API 端点的请求最好使用相同的 url。我认为这个答案仍然没有涵盖那种情况???
  • @chanp 正确,它不包括这种情况。这种情况只能通过标题来解决,但 chrome v33 会覆盖其中的一些......所以......是的,祝你好运 :)
【解决方案2】:

由于多种原因,现在使用查询字符串进行缓存控制并不是您的最佳选择,并且(仅)在this answer 中提到了一些。他甚至解释了版本控制的新标准方法。虽然如果您只想设置请求标头,那么正确的做法是:

    // via Cache-Control header:
    xhr.setRequestHeader("Cache-Control", "no-cache, no-store, max-age=0");
    
    // fallbacks for IE and older browsers:
    xhr.setRequestHeader("Expires", "Tue, 01 Jan 1980 1:00:00 GMT");
    xhr.setRequestHeader("Pragma", "no-cache"); //Edit: I noticed this is required for Chrome some time ago... forgot to mention here

希望这对将来的任何人都有帮助。

【讨论】:

  • 注意:如果设置了max-age,则不需要expires (source);不需要post-check=0pre-check=0 (source); must-revalidate 不能用于客户端 (source)。
  • 它们可能不是必需的,但是有些旧浏览器会忽略其他一些标头,在这种情况下,它们会开始执行这项工作(我自己已经使用 crossbrowsertesting 对此进行了测试。 com)。虽然我不能保证must-revalidate,因为我对此了解不多,只是为了矫枉过正。
【解决方案3】:

我尝试(但失败了)对 URL 进行某种随机化,但它不起作用,因为我正在访问的文件 (.json) 也被缓存了。

我的解决方案是在对 json 文件名的调用中添加时间戳(与上述方法类似,稍作修改)。这对我来说非常有效(下面的代码 sn-p)。

doSomething('files/data.json?nocache=' + (new Date()).getTime(), function(text){...

我对这一切都很陌生,所以我确信这不是标准/正确的解决方案是有原因的,但它对我有用。

【讨论】:

    【解决方案4】:
    http.setRequestHeader("Cache-Control", "no-cache, no-store, must-revalidate");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-25
      • 2011-07-02
      • 1970-01-01
      • 2021-04-12
      • 2012-06-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多