强制缓存控制:在 F5 重新加载时通过 XMLHttpRequest 在 Chrome 中无缓存

IT技术 javascript ajax google-chrome caching
2021-02-24 00:45:31

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

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

例子。将内容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 显示了类似的行为。Intead 只是覆盖请求标头,它将其修改为 Cache-Control: no-cache, max-age=0 on F5。

我可以压制这个吗?

4个回答

另一种方法是在 url 后附加一个唯一的数字。

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

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

@chanp 正确,它不包括这种情况。这种情况只能用标头解决,但 chrome v33 覆盖了其中的一些......所以......是的,祝你好运:)
2021-04-26 00:45:31
在某些情况下,对同一 API 端点的请求最好使用相同的 url。我认为这个答案仍然没有涵盖那种情况???
2021-05-07 00:45:31
请注意,这个答案是一个社区维基,所以如果您觉得它不能充分回答问题,请随时更新它。我没有时间自动取款机重新审视它。
2021-05-14 00:45:31
2021-05-17 00:45:31
@wadim 所以 Chrome 和 Firefox 不尊重 RFC 2616(现在是 7234)?
2021-05-20 00:45:31

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

    // 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

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

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

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

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

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

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

http.setRequestHeader("Cache-Control", "no-cache, no-store, must-revalidate");