在Chrome中使用window.location.reload和散列片段从缓存加载不起作用

时间:2013-06-01 13:32:50

标签: javascript http google-chrome caching browser-cache

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

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

资源的响应标头如下:

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应该使用它的内部缓存,而不是向服务器发送任何内容。

使用Firefox的相同代码没有问题,FF使用缓存版本而根本没有连接到服务器。

我该如何解决这个问题?

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

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

编辑2:请注意,如果关闭标签并将网址输入新网址,则Chrome会正确使用缓存。只有点击链接(会导致window.location.reload)才会受到影响。

4 个答案:

答案 0 :(得分:3)

经过一番研究后回答自己:

根本无法完成。

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

似乎window.location.reload()不能用于控制当前资源(由window.location.href指示)是否要从缓存中使用。虽然MDN上的文档提示不然。 Location对象中window对象的官方W3C规范也没有多大帮助。

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

我可以观察到布尔参数的存在会影响浏览器是否会向请求附加Cache-Control: max-age=0标头。但这只会减少传输的数据,并且根本不会消除服务器连接。无论如何都要完成往返。

答案 1 :(得分:1)

latest HTML5 draft中(可能会在没有修改的情况下成为最终的HTML5标准)location.reload()函数不再使用任何布尔参数。因此,在定位HTML5时,不应以任何方式依赖参数。

答案 2 :(得分: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();
}

答案 3 :(得分:0)

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

如果浏览器不会在缓存中查找以重新加载页面,并且当跟踪链接仅按片段不同时它不会重新加载页面,请尝试欺骗它以为它正在加载一个不同的页面来获取它查看缓存。这使用ajax从缓存中获取您正在查看的页面,并用它替换整个文档。然后它用一个新片段替换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>