1

我需要用 Javascript 重新加载页面。我window.location.reload用于此目的。现在,我在 Chrome 中观察到一个奇怪的行为:Chrome 总是连接到服务器并询问文档是否被修改。虽然304 Not Modified返回了 a ,但我仍然想避免往返服务器。

我也尝试过明确地使用window.location.reload(false)告诉 chrome 使用缓存,但没有成功。并不是说我在重新加载的 url 中有一个活动的哈希 (#) 片段。

资源的响应头如下:

HTTP/1.1 304 Not Modified
Server: nginx/1.2.2
Date: Sat, 01 Jun 2013 13:19:56 GMT
Last-Modified: Sat, 01 Jun 2013 13:04:55 GMT
Connection: keep-alive
Expires: Sun, 02 Jun 2013 13:19:56 GMT
Cache-Control: max-age=86400
Access-Control-Allow-Origin: *

因此,Cache-ControlExpires标头都已设置,应该告诉 chrome 不要在 24 小时内更新资源。

我没有使用 F5/CMD+R 重新加载页面,而是单击一个链接,该链接将具有一个 javascript 事件,该事件将更改window.location.hash然后调用window.location.reload(false). 但是 Chrome 一直在Cache-Control: max-age=0为请求设置标头 - 我不想要。Chrome 应该使用它的内部缓存,并且根本不向服务器发送任何内容。

相同的代码使用火狐没有问题,FF使用的是缓存版本,根本不连接服务器。

我怎样才能解决这个问题?

编辑:这是一个简单的示例,您可以自己试用:http ://webspace.markdown.io/reloadtest.html

编辑:我关闭了开发人员工具并通过tcpdump -s 1024 -l -A dst port 80服务器验证标头。我还在开发人员工具中取消了“禁用浏览器缓存”。

编辑 2:请注意,如果关闭选项卡并将 URL 输入新的,Chrome 会正确使用缓存。仅单击一个链接(这将导致 awindow.location.reload受到影响。

4

4 回答 4

3

经过更多研究后回答自己:

根本做不到。

问题根本与hash值无关,即使您不使用散列也会出现。

它似乎window.location.reload()不能用于控制是否window.location.href要从缓存中使用当前资源(由 表示)。尽管MDN上的文档另有说明。Location对象中对象的官方 W3C 规范window也没有太大帮助。

Chrome 和 Firefox 将始终执行到服务器的往返,询问当前资源,无论您传递什么参数.reload()。最初引入该参数是为了强制POST请求作为GET请求重复 - 这与缓存无关。(使用 Firebug 时要小心:我首先认为 FF 不会发送请求,因为它没有显示在 Firebug 中 - 但是当您查看网络服务器日志时,您会发现它确实发送了)。

我可以观察到布尔参数的存在会影响浏览器是否将Cache-Control: max-age=0 标头附加到请求中。但这只会减少传输的数据,并不会完全消除服务器连接。在任何情况下都会进行往返。

于 2013-06-11T20:34:54.703 回答
1

最新的 HTML5 草案(很可能成为最终的 HTML5 标准而无需修改)中,该location.reload()函数不再采用任何布尔参数。因此,在以 HTML5 为目标时,不应以任何方式依赖该参数。

于 2014-11-12T08:36:04.117 回答
0

使用 F5 或 重新加载页面window.location.reload会建立网络连接,即使从不同页面导航到该页面会直接在缓存中查看。虽然reload(true)强制它绕过缓存(200从服务器而不是从服务器获取304),reload(false)但不会强制它在决定是否需要连接到服务器之前查看缓存。

如果浏览器不会在缓存中查找以重新加载页面,并且当跟随仅与片段不同的链接时它不会重新加载页面,请尝试欺骗它以为它正在加载不同的页面以使其查看缓存。这使用 ajax 来获取(从缓存中)您已经在查看的页面,并用它替换整个文档。然后它用一个新的 URI 片段替换该 URI 片段——以这种方式更改片段会触发 JavaScript 框架中的任何函数侦听片段中的更改。

<html>
<head>
    <script src="http://code.jquery.com/jquery-1.8.1.min.js"></script>
</head>
<body>
    <p>
        It is: <span id="thetime"></span>
    </p>
    <a href="javascript: reload_page()">Reload</a>
    <script type="text/javascript">
        function reload_page() {
            var hash = new Date().getTime()
            $.get(window.location, function(data) {
                var newDoc = document.open("text/html", "replace");
                newDoc.write(data);
                newDoc.close();
                window.location.hash = new Date().getTime();
            });
        }
        document.getElementById('thetime').innerHTML = new Date().toISOString();
    </script>
</body>
</html>
于 2013-06-11T09:39:01.443 回答
0

你可以这样做:

function reload_page() {
    window.location.hash = new Date().getTime();
    window.location.replace(window.location.href);
    loaded();
}
window.onload = loaded;

function loaded() {
    document.getElementById('thetime').innerHTML = new Date().toISOString();
}
于 2013-06-09T11:21:14.530 回答