2009-05-22 2 views
22

я добавил следующую строку в моей Apache httpd.conf: -Apache не посылает 304 ответа (если mod_deflate и AddOutputFilterByType включено)

AddOutputFilterByType DEFLATE text/html text/css application/javascript application/x-javascript application/json 

У меня есть HTML-файл (test.html) с включение скрипта: -

<script type="text/javascript" src="/test.js"></script> 

проблема заключается в том, каждый раз, когда я загружаю test.html, test.js также загружаются с состоянием HTTP: 200.

вопрос: Почему условный GET я не удовлетворены?

Если я закомментировать строку "AddOutputFilterByType" в httpd.conf, Apache посылает 304.

Если включить AddOutputFilterByType в httpd.conf, заголовок запроса: -

 
Host: optimize 
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10 GTB5 (.NET CLR 3.5.30729) FirePHP/0.2.4 
Accept: */* 
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 
Keep-Alive: 300 
Connection: keep-alive 
Referer: http://optimize/ 
Cookie: PHPSESSID=nbq6h0eeahkshkcbc6ctu2j2b4 
If-Modified-Since: Tue, 19 May 2009 07:06:46 GMT 
If-None-Match: "2000000000717f-2c25a-46a3e8dcc2ad8"-gzip 
Cache-Control: max-age=0 

И заголовок ответ: -

 
Date: Fri, 22 May 2009 07:03:40 GMT 
Server: Apache/2.2.9 (Win32) PHP/5.2.6 
Last-Modified: Tue, 19 May 2009 07:06:46 GMT 
Etag: "2000000000717f-2c25a-46a3e8dcc2ad8"-gzip 
Accept-Ranges: bytes 
Vary: Accept-Encoding 
Content-Encoding: gzip 
Content-Length: 52583 
Keep-Alive: timeout=5, max=98 
Connection: Keep-Alive 
Content-Type: application/javascript 

UPDATE: Я заметил, если я отключить ETag, он работает правильно. Я имею в виду, что посылает 304.

FileETag None 

Но я действительно хочу, чтобы ETag, как это (я знаю, что есть проблема раскрытия инода).

+1

ли вы когда-нибудь найти обходной путь? Apache 2.4, похоже, делает то же самое, всегда отправляя 200 ответов для содержимого gzip'd – virtualeyes

+0

Любые причины, по которым вы хотите сохранить ETags? Их нет, если вы просто статичный контент, который уже имеет дату «Last-Modified» для повторной аттестации. Разумеется, их осциллирование было бы самым легким временным решением, совместимым с RFC. –

+0

ETags * * необходимо.Если вы когда-либо захотите заменить контент на более старую версию (например, файл javascript, который нужно было вернуть к более старой версии без ошибки, которая была введена), а при повторном использовании устаревшей даты файла, то простого сравнения даты не будет достаточно , –

ответ

0

Возможно, вы используете прокси-сервер (squid), который управляет HTTP-запросами?

+0

Нет, я не использую прокси. Я даже пытаюсь в своем локальном хосте. Тот же результат. – Sabya

19

Это известная ошибка в Apache. См. Apache bug #45023 и summary of Apache 304 etags and mod_deflate.

Реконструкция из svn решит проблему. Резолюция состояла в том, чтобы вернуть изменение, добавленное «-gzip» в etag. Тем не менее, существуют связанные с HTTP проблемы соответствия.

Если вы не можете восстановить Apache, есть предложил конфигурации во время выполнения обхода в отчете об ошибке:

RequestHeader edit "If-None-Match" "^\"(.*)-gzip\"$" "\"$1\"" 
Header edit "ETag" "^\"(.*[^g][^z][^i][^p])\"$" "\"$1-gzip\"" 
+3

На Apache 2.4, ничего, кроме ответов «200 OK» - действительно ли это решение работает? – virtualeyes

+3

Это ВСЕ ЕЩЕ проблема, и я не мог работать выше (в Apache 2.4.7). Однако, после некоторого дополнительного копания, я также решил, что ETags не так полезны в Apache. ETag был бы наиболее полезен, если бы он был хешем содержимого, поэтому, даже если временная метка изменилась, его все равно можно использовать, чтобы решить, нет ли содержимого. Для Apache ETag представляет собой комбинацию индексов, размеров и последних модифицированных данных (с размерами и последними измененными значениями, используемыми по умолчанию). Поэтому, поскольку он использует атрибуты файлов, а не хеш содержимого, я решил отключить его и использовать Last-Modified. –

+2

Кажется, что STILL проблема? Я использую Apache 2.4.10 – Inna

8

«Я также решил, что ETags не так уж полезны в Apache в любом случае. "

Неправильно,
, например, у вас есть файл с датой модификации, установленной в '2016.07.27 05:00:00', вы загрузите его на свой сайт, браузер получает этот файл с кодом 200 HTTP, а затем кэширует его и источ- никто каждый раз с HTTP 304.
Затем вы снова загружаете файл с тем же именем, но с более старой отметкой времени '2013.07.27 05:00:00' и с другим контентом.

Если ETag отключен на сервере, браузер будет использовать только запрос If-Modified-Since:, чтобы определить, был ли файл изменен на сервере, поэтому запрос будет If-Modified-Since: 2016.07.27 05:00:00, но после этой даты файл не будет изменен, поэтому возвращается HTTP 304, даже если файл был изменен.

Если на сервере включен ETag, кроме If-Modified-Since:, будет создан заголовок If-None-Match:, который будет обнаруживать, что файл был изменен (по умолчанию - несоответствие времени и несоответствие размера), и файл будет перезагружен.


Эта проблема все еще существует в Apache 2.4.23, поэтому я написал код лучше, чем выше, чтобы устранить эту проблему. Развертка по строкам:

    1) Если браузер отправляет запрос «If-None-Match», который имеет «-gzip» в конце, задайте переменную request_etag = gzip.
    2) Измените заголовок запроса, чтобы вырезать часть «-gzip».
    3) Отредактируйте заголовок ответа, чтобы добавить часть «-gzip», но только если браузер отправил запрос «-gzip» изначально, или содержимое ответа было закодировано gzip.


Вы можете использовать либо отрицательный предпросмотр или отрицательные назад ', скорость регулярного выражения такого же, Apache поддерживает оба

\"(.+(?<!-gzip))\"  #using negative lookbehind 
\"((?:.(?!-gzip\"))+)\" #using negative lookahead 

случаев тестов:

    «2E2 -5388f9f70c580-afeg "
    "2e2-5388f9f70c580-gzin"
    "2e2-5388f9f70c580-gzipd"
    "2e2-5388f9f70c580gzip"
    "2e2-5388f9f70c580gzip"

Copy-Paste этот код в Apache .conf

SetEnvIf   If-None-Match "-gzip\"$" request_etag=gzip 
RequestHeader edit If-None-Match "(.+)-gzip\"$" "$1\"" 
Header edit  ETag  "(.+(?<!-gzip))\"$" "$1-gzip\"" "expr=reqenv('request_etag') == 'gzip' || resp('Content-Encoding') == 'gzip'" 


Я лично использую следующий код, который сначала начищает '-gzip' часть, если это ответ gzip, и не обновляет его, поэтому браузер никогда не отправит заголовок '-gzip' 'If-None-Match'.

Header edit ETag "(.+)-gzip\"$" "$1\"" "expr=resp('Content-Encoding') == 'gzip'" 
+0

Проблема все еще существует в Apache 2.4.25. Этот 3-строчный код помог мне, но мне нужно было включить 'headers_module'. – ilhan

0

Я знаю, что это очень старый вопрос, но это, кажется, есть более уточненный ответ.

Чтобы Apache не добавлял суффикс -gzip, вы должны использовать директиву DeflateAlterETag со значением NoChange.

Смотрите документацию для этого здесь: http://httpd.apache.org/docs/trunk/mod/mod_deflate.html#deflatealteretag

Смежные вопросы