Заставить браузеры обновлять кэшированные и удаленные изображения - PullRequest
2 голосов
/ 27 октября 2011

Сгенерированные пользователем изображения на моем сайте обрабатываются с помощью src, например:

userImage.ashx?id={UserId}&type=avatar

В ответе из файла ashx я установил заголовок etag. Когда пользователь загружает новое изображение, etag изменяется.

Если в браузере есть файл, кэшированный с etag, он должен отправлять запрос на сервер с заголовком If-None-Match, установленным на этот etag, всякий раз, когда ему нужно отобразить этот файл. Если кэшированный etag совпадает с текущим etag на сервере, сервер отвечает Not Modified - 304. Если etag отличается, сервер отвечает OK - 200 и начинает отправку нового файла.

Вот как это должно работать в теории. Тем не менее, я обнаружил, что для некоторых браузеров (Firefox и IE, не протестированных на других) это не так. Если пользователь переходит на новую страницу с кэшированными, размеченными изображениями, эти браузеры просто используют изображение из своего кэша без запроса. Если пользователь затем обновляет страницу, браузер отправляет запрос с установленным заголовком If-None-Match.

Итак, моя проблема заключается в следующем: пользователь обновляет одно из своих изображений, а затем переходит на страницу с изображением. Пока пользователь не нажмет refresh, кэшированное изображение будет отображаться, даже если оно отличается от нового изображения. Когда пользователь нажимает кнопку обновления, браузер выполняет запрос с набором заголовков If-None-Match, который запускает отправку сервером нового изображения.

Можно ли это исправить?

Пример 200 заголовка ответа:

Status=OK - 200
Date=Thu, 27 Oct 2011 14:37:31 GMT
Server=Microsoft-IIS/6.0
X-Powered-By=ASP.NET
X-AspNet-Version=4.0.30319
Transfer-Encoding=chunked
Cache-Control=public, max-age=86400
Etag="27/10/2011 13:23:30"
Content-Type=image/jpg

Пример 304 header:

Status=Not Modified - 304
Connection=close
Date=Thu, 27 Oct 2011 14:39:12 GMT
Server=Microsoft-IIS/6.0
X-Powered-By=ASP.NET
X-AspNet-Version=4.0.30319
Cache-Control=public, max-age=86400

(Использование последней измененной даты в качестве etag в качестве более адаптируемой для последующих нужд, касающихся сжатия и т. Д.)

Ответы [ 2 ]

2 голосов
/ 27 октября 2011

IIRC вы можете установить срок действия файла через заголовок «Expires». Поэтому, если вы скажете «Этот файл действителен в течение следующих двух дней», у браузера нет причин связываться с вашим сервером.

max-age, как указано в вашем примере, делает то же самое, в основном.

0 голосов
/ 29 февраля 2012

Я решил эту проблему следующим образом:

Иметь службу на стороне сервера, которая всегда перенаправляет (с 302 перемещено временно) на изображение, которое вы хотите показать, а на стороне пользователя источник изображения должен быть сброшен вперенаправление + '?'+ timestamp.

Это заставляет браузер снова запрашивать изображение, но позволяет кешу работать.

Так, например, ваш пользовательский JavaScript запрашивает /redirectme/avatar-xxx.jpg?121341 и получает от 302 до /avatars/avatar-xxx.jpg который он обычно запрашивает с кэшированием Etag.Вы платите две поездки туда и обратно за то, что вам не нужно каждый раз отправлять целое изображение.

Протестировано в Chrome 19 (не требуется строка запроса временной метки) и Firefox 10 (нужна временная метка).

...