9

Есть ли способ заставить клиентов веб-страницы перезагрузить кеш (например, изображения, javascript и т. Д.) После того, как сервер был перенесен на базу кода? Мы получаем много звонков в службу поддержки, спрашивая, почему определенные функции больше не работают. Простое жесткое обновление устраняет проблемы, поскольку оно загружает обновленный файл javascript.Заставить браузер перезагрузить весь кеш после обновления сайта

Для специфики мы используем Glassfish 3.x. и JSF 2.1.x. Конечно, это касается не только JSF.

Чтобы описать то, что поведение, я надеюсь, что это возможно:

Сайт А имеет два изображения и два JavaScript-файлов. Пользователь посещает сайт, и 4 файла получают кеширование. Насколько мне известно, нет необходимости «повторно загружать» указанные файлы, если только пользователь не заставляет «жестко» обновлять или очищать свой кеш. После того как сайт будет перенаправлен на обновление одного из файлов, сервер может иметь какие-то метаданные в заголовке, информирующие клиента об этом обновлении. Если клиент выбирает, будут загружены новые файлы.

То, что я не хочу делать, это поместить метатег в заголовок страницы, чтобы ничего не кэшировать ... Я просто хочу что-то, что говорит клиенту о произошедшем обновлении, и он должен получить последний раз, когда что-то обновлено. Полагаю, это будет просто какая-то версия на стороне клиента.

Спасибо за ваше время!

ответ

12

Правильный способ справиться с этим заключается в изменении соглашения об URL для ваших ресурсов. Например, у нас есть как:

/resources/js/fileName.js 

Чтобы получить браузер по-прежнему кэшировать файл, но сделать это надлежащим образом с версиями, является то добавить к URL. Добавление значения к querystring не позволяет кэшировать, поэтому место для его размещения следует после /resources/.

Ссылка для QueryString кэширования: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.9

Так, например, ваши адреса будут выглядеть следующим образом:

/resources/1234/js/fileName.js 

Так что вы можете сделать, это использовать номер версии проекта (или некоторое значение в свойствах/config, который вы вручную измените, когда вы хотите перезагрузить кешированные файлы), поскольку этот номер должен изменить только при изменении проекта. Таким образом, ваш URL-адрес может выглядеть так:

/resources/cacheholder${project.version}/js/fileName.js 

Это должно быть достаточно простым.

Проблема теперь в сопоставлении URL-адреса, поскольку это значение посередине является динамическим. Как мы преодолели это с модулем перезаписи URL-адресов, который позволил нам фильтровать URL-адреса, прежде чем они попали в наше приложение.Переписывают наблюдал за URL-адресов, которые выглядели как:

/resources/cacheholder______/whatever 

и удалили cacheholder_______/ часть. После перезаписи это выглядело как обычный запрос, и сервер ответил бы правильным файлом, без какого-либо другого конкретного отображения/логики ... Дело в том, что браузер думал, что это новый файл (хотя он действительно был не " t), поэтому он запросил его, и сервер определил его и подал правильный файл (хотя это «странный» URL-адрес).

Конечно, другой вариант заключается в том, чтобы добавить эту динамическую строку к самому имени файла, а затем использовать инструмент перезаписи для его удаления. В любом случае, то же самое делается - таргетинг на строку текста во время перезаписи и удаление. Это позволяет обмануть браузер, но не сервер :)


UPDATE:

Альтернативой, что мне очень нравится, чтобы установить имя файла на основе содержимого, а кэш, что. Например, это можно сделать с помощью хэша. Конечно, этот тип вещей - это не то, что вы делали вручную и сохраняете в своем проекте (надеюсь); это то, над чем должно работать ваше приложение/инфраструктура. Например, в Grails, есть плагин, который «хэши и кэши» ресурсов, так что происходит следующее:

  • Каждый ресурс проверяется
  • новый файл (или отображение на этот файл) создается с имя, которое является хэш его содержимого
  • При добавлении <script>/<link> теги на странице, то хэшируются имя используется
  • Когда хэш-имени файла запрашивается, он служит оригинальный ресурс
  • hash- Именованный файл кэшируется «навсегда»

Что нового в этой настройке: вам не нужно беспокоиться о кешировании правильно - просто установите файлы на кеш навсегда, и хеширование должно заботиться о файлах/сопоставлениях, доступных на основе контента. Он также обеспечивает возможность отката/отмены, которые уже будут кэшироваться и загружаться быстро.

+0

«Добавление значения к querystring не позволяет кэшировать» - из документации, которую я прочитал, этот оператор является неточным. HTTP GET_are_ кэшируется браузером с строкой запроса или без нее. См. Http://www.w3schools.com/tags/ref_httpmethods.asp – pmont

+0

@pmont Пожалуйста, не ссылайтесь на W3Schools по фактической документации W3. Ваша точка недействительна, пожалуйста, прочитайте ссылку, которую я разместил, или предоставили что-то более законное. – Ian

+0

Не нужно злиться на меня. Веб-серверы, которые я развернул, имеют все кэшированные запросы. Какой сервер (ы) вы наблюдали, не кэшируя их? Из вашей ссылки: «Это означает, что ответы от серверов HTTP/1.0 для таких URI НЕ ДОЛЖНЫ быть взяты из кеша». «Может быть, изменения в HTTP/1.1 могут объяснить различное поведение? – pmont

0

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

$no_cache = "v11"; 

и на страницах, я использую такие активы, как

<img src="a.jpg?nc=$no_cache"> 

, и когда я обновляю свой код, просто измените значение $ no_cache, и оно работает как шарм.

+0

Но, как вы указали, это никогда не позволяет кэшировать ресурс. Зачем вам это нужно? – Ian

+0

, если вы не измените значение no_cache, статические файлы будут кэшироваться. сделайте это изменение только тогда, когда вы изменили статический материал. – tanaydin

+0

Нет, это неправда. Все, что связано с querystring, не должно кэшироваться, согласно спецификации HTTP. Некоторые браузеры следуют за этим, некоторые - нет. Поэтому браузер всегда будет делать запрос, так как в конце есть запрос. Возможно, сервер кэширован, что хорошо, но он все еще не кэшируется на клиенте. – Ian