Загрузка из кэша с помощью window.location.reload и хэш-фрагмента в Chrome не работает

1 Dynalon [2013-06-01 16:32:00]

Мне нужно перезагрузить страницу в Javascript. Для этой цели я использую window.location.reload. Теперь я наблюдаю странное поведение в Chrome: Chrome всегда подключается к серверу и спрашивает, был ли документ изменен. Хотя возвращается 304 Not Modified, на сервере все еще есть обратная связь, которую я хочу избежать.

Я также попытался явно использовать 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-Control и Expires оба установлены и должны сообщать chrome, чтобы не обновлять ресурс в течение 24 часов.

Я не перезагружаю страницу, используя F5/CMD + R, но вместо этого я нажимаю ссылку, которая будет иметь событие javascript, которое изменит window.location.hash а затем вызовет window.location.reload(false). Но Chrome продолжает настраивать заголовок Cache-Control: max-age=0 для запроса, чего я не хочу. Chrome должен использовать внутренний кеш и вообще ничего не отправлять на сервер.

Нет проблем с тем же кодом, что и Firefox, FF использует кешированную версию без подключения к серверу вообще.

Как я могу это исправить?

EDIT: Вот простой пример, который вы можете использовать для опроса самостоятельно: http://webspace.markdown.io/reloadtest.html

EDIT: У меня есть инструменты разработчика закрыты и проверьте заголовки через tcpdump -s 1024 -l -A dst port 80 на сервере. Я также отключил "отключить кеш браузера" в инструментах разработчика.

EDIT 2: Обратите внимание: если закрыть вкладку и ввести Url в новый, Chrome правильно использует кеш. Возникает только щелчок по ссылке (которая приведет к возникновению window.location.reload.

javascript http google-chrome caching browser-cache


4 ответа


3 Решение Dynalon [2013-06-11 23:34:00]

Отвечая на вопрос, после нескольких исследований:

Это просто невозможно.

Проблема вообще не связана с hash значением и возникает, даже если вы не используете хэш.

Кажется, window.location.reload() не может использоваться для контроля того, должен ли текущий ресурс (указанный window.location.href) использовать из кеша или нет. Хотя в документации по MDN говорится об обратном. Официальные спецификации W3C в объекте Location объекте window также не очень помогают.

Chrome и Firefox всегда будут выполнять .reload() с сервером, запрашивая текущий ресурс, независимо от того, какой параметр вы передаете .reload(). Параметр был первоначально введен, чтобы заставить запросы POST повторяться как запросы GET - это не имеет никакого отношения к кешированию. (Осторожно при использовании Firebug: я сначала подумал, что FF не отправляет запрос, потому что он не показан в Firebug, но когда вы смотрите на журналы веб-сервера, вы можете видеть, что это действительно так).

Я могу заметить, что наличие логического параметра влияет на то, будет ли браузер добавлять к запросу заголовок Cache-Control: max-age=0. Но это только уменьшает передаваемые данные и вообще не отменяет соединение с сервером. Во всяком случае, в любом случае.


1 Dynalon [2014-11-12 11:36:00]

В последнем проекте HTML5 (который, вероятно, станет окончательным стандартом HTML5 без изменений location.reload() функция location.reload() больше не принимает никакого логического параметра. Поэтому не следует полагаться на параметр каким-либо образом при таргетинге на HTML5.


0 Jordan [2013-06-11 12:39:00]

Перезагрузка страницы с помощью 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>

0 A. Wolff [2013-06-09 14:21:00]

Вы могли бы сделать что-то вроде этого:

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();
}