Заголовки для запобігання 304 / If-modified-since / HEAD запитів


31

Які заголовки мені слід надсилати, щоб остаточно зупинити всі запити на сервері після кешування вмісту?

У нас дуже високий рівень затримки (Sigh, VMWare), тому навіть відправка HEADзапиту на сервер займає + 40 мс.

В даний час це заголовки, що надсилаються / приймаються;

Перший запит

Клієнт відправляє;

GET http://dugong:8080/Rvi24mYJkxFRGNzq73PPvgWGh1j/IMG_2071.jpg HTTP/1.1
Host: dugong:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:9.0) Gecko/20100101 Firefox/9.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Pragma: no-cache, no-cache, no-cache
Cache-Control: no-cache, no-cache, no-cache

Сервер відповідає;

HTTP/1.1 200 OK
Server: nginx/1.0.11
Date: Wed, 01 Feb 2012 14:51:51 GMT
Content-Type: text/plain
Vary: Accept-Encoding
Last-Modified: Tue, 31 Jan 2012 10:45:11 GMT
Content-Length: 14
Expires: Thu, 31 Jan 2013 14:51:51 GMT
Cache-Control: max-age=31536000

Таким чином , він посилає Cache-Controlі Expiresнабір заголовків 365 днів в майбутньому. На жаль, при другому оновленні він знову запитує об'єкт із If-Modified-Sinceзаголовком.

Другий запит

GET http://dugong:8080/Rvi24mYJkxFRGNzq73PPvgWGh1j/IMG_2071.jpg HTTP/1.1
Host: dugong:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:9.0) Gecko/20100101 Firefox/9.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
If-Modified-Since: Tue, 31 Jan 2012 10:45:11 GMT
Cache-Control: max-age=0

Відповідь;

HTTP/1.1 304 Not Modified
Server: nginx/1.0.11
Date: Wed, 01 Feb 2012 14:58:00 GMT
Vary: Accept-Encoding
Expires: Thu, 31 Jan 2013 14:58:00 GMT
Cache-Control: max-age=31536000

На жаль, через нерозумно застаріле проксі-програмне забезпечення ми не можемо використовувати Keep-Aliveабо розміщувати будь-які інші сервери / проксі перед додатком. Ми також не можемо покращити продуктивність сервера та зменшити затримку в мережі. Я намагався розібратися, які заголовки ми можемо надіслати, щоб позбутися 301 запиту. Я намагався використовувати ETags, але це не має ніякого значення, він все одно надсилає If-modified-sinceзаголовок. Я також спробував видалити Last-Modifiedзаголовок, але це просто спричиняє стандартний GET-запит без кешування (Перевірено журнали, сервер все ще отримує запити).

Клієнти - це поєднання Firefox (здебільшого), IE 7, 8 та (деякі) 9, Chrome та Safari, але така поведінка виявляється у всіх перевірених браузерах.

TL; DR;

Страшна мережа, які заголовки потрібно надіслати клієнтам, щоб ніколи ніколи не надсилали If-modified-sinceзапити на сервер для перевірки їх кешу і зберігали кешований вміст, поки не Expiresбуде виконано заголовок?

Я, мабуть, пропускаю щось очевидне, але все, що я намагаюся, дає такі самі результати.

У нас на сервері додатків сидів сервер NGINX, тому я можу додавати / видаляти будь-які заголовки, як мені заманеться. Наш проксі-сервер не підтримує Keep-Alive і їхній спосіб не покращити витончені показники роботи мережі. Через жахливий дизайн програмного забезпечення веб-додаток завантажує +100 ресурсів на кожній завантаженій сторінці (Так, програмне забезпечення підприємства відсмоктується) із затримкою ~ 40-50мс на об'єкт.


1
Гм, це дивно. Відправлення заголовків Expires та max віку має запобігати подальшим запитам зображення. Редагувати: до речі, яка угода з надсиланням JPG text/plain?
НезадоволенняГота

1
@DisgruntledGoat Ааа, ви зробили припущення, що .jpg файл - це насправді зображення, а не текстовий документ. Ласкаво просимо в мій світ =) (Насправді це текстовий файл, який містить "Hello World" для мого тестування. Програма просто перейменовує всі файли послідовно IMG_xxxx.jpg незалежно від типу. Класно, так?)
Помазання

що ви використовували для встановлення заголовків http запиту?
барлоп

Відповіді:


25

Ви дійсно не можете контролювати, які агенти користувачів заголовків вирішують надіслати вам. Якщо відповідний файл знаходиться в кеші браузера, і він вирішить, що потрібно перевірити нову версію, він буде. Згідно з цією статтею , такі ситуації браузери вимагатимуть із використанням If-Modified-Since:

  • У кешованому записі немає дати закінчення терміну придатності, і до вмісту вперше доступний сеанс браузера
  • У кешованому записі є термін придатності, але термін його дії закінчився
  • Користувач запитав оновлення сторінки, натиснувши кнопку «Оновити» або натиснувши F5

Тож якщо ви перезавантажуєте сторінку для перевірки кешування, вона не працюватиме, оскільки браузер повторно вимагатиме зображення. Спробуйте натиснути посилання, а потім інше посилання на першу сторінку. Якщо ваші користувачі регулярно перезавантажують сторінки, можливо, вам знадобиться переосмислити структуру свого веб-сайту / програми, щоб цього не допустити.

Одне, що може допомогти - це додавання "public" до заголовка кеша керування, тобто Cache-Control: public, max-age=31536000. Нещодавно я також дізнався, що термін придатності понад один рік недійсний. Оскільки термін придатності закінчується рівно на рік, можливо, скорочення на кілька днів або тижнів забезпечить збереження файлу в кешах браузера і не буде відкинуто.


Цікаво, що я знижу термін дії до 60 днів і додамо публічний прапор, і подивіться, що станеться. Це, здавалося, відбувається на кліках посилань, а не на F5 (згідно Firebug та журналів сервера)
Smudge

Технічно специфікація HTTP / 1.1 говорить лише про те, що "сервери НЕ БУДЕ надсилати терміни придатності більше ніж один рік у майбутньому" (мабуть тому, що це смішно задовго до закінчення терміну) і що "приблизно один рік" у майбутньому є відповідним закінченням час надіслати вміст, який ніколи не очікується закінчився.
Ільмарі Каронен

1
Трохи погравши, я прийшов до висновку, що термін дії 365d не впливає на наших клієнтів, однак я знизив його, щоб бути безпечним Cache-Control: public,....
Мазок

Ви маєте на увазі, що "загальнодоступний" заголовок зафіксував непотрібні об'їзди? Я спробував це, але без успіху ...
phtrivier

2
У випадку, якщо з моєї відповіді це не зрозуміло, при перезавантаженні сторінки у вашому браузері знову буде подано запит на файли . Просто натисніть посилання, щоб відкрити сторінки, і браузер використовує кеш-пам'ять.
НезадоволенняГота


3

У мене була така ж проблема, і Запити, безумовно, потрапляють на сервер, щоб він відповів 304статусом - я надсилаю 304 через деякий C # і, звичайно, він потрапляє на сервер ..

Я тільки Cache-Control: privateвстановив. Ні max-ageта ні. ExpiresЦе діяло, як очікувалося; натисніть сервер там, If-Modified-Sinceде я перевіряю значення порівняно з тим, що я очікую, і доставляю 304ж / порожнє тіло відповіді - ще 200й заповніть тіло відповіді.

Налаштування Expiresзаголовка мала бажані результати, коли 200 - (from cache)клієнт & HTTP-запити не потрапляли на сервер.

Але .. Я виявив, що встановлення BOTH max-age= & Expiresможе призвести до того, що браузери не надсилають If-Modified-Sinceзаголовка І взагалі не кешуватимуть, якщо значення не збігаються .

Що потрібно пам’ятати, якщо у вас є проблеми з кешуванням та використовуєте різні заголовки в поєднанні.


1

Трохи поза темою, але, можливо, корисно. Ще одне вдосконалення ваших запитів кешованого вмісту - це кешування у sessionStorage, щоб вам не потрібно було просити сервер перевірити кеш і отримати 304. Шукайте, наприклад, Google, відкрийте консоль і запишіть sessionStorage. Ви побачите, що вони кешують CSS або DOM за допомогою sessionStorage. ofc, ви не можете використовувати це в старих браузерах IE.


0

Перегляньте свій вихідний код і переконайтесь, що немає переробки META для переходу на іншу сторінку. Використовуйте щось подібне sendRedirect. У моїх налаштуваннях META REFRESH виробляє 304s в IE, але не в Chrome. sendRedirect не створює цього в жодному браузері.

<meta http-equiv="refresh" content="0;URL='nextpage'" />    

проти

<% response.sendRedirect("nextpage") %>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.