Как удалить заголовки eTag из IIS7?

83

Согласно рекомендациям Yahoo для высокопроизводительных веб-сайтов , я бы хотел удалить Etags из своих заголовков (я вручную управляю всем своим кешированием, и мне не нужны Etags ... и когда / если мне нужно масштабировать до фермы, Я бы очень хотел, чтобы они ушли). Я использую IIS7 на Windows Server 2008. Кто-нибудь знает, как я могу это сделать?

Джефф Этвуд
источник
Он работает для IIS 8.0 и далее, по крайней мере, как показано во втором ответе этого сообщения: stackoverflow.com/questions/7947420/…
RBT

Ответы:

39

В IIS7 номер изменения Etag (часть Etag, следующая за:) всегда имеет значение 0.

Следовательно, Etag с сервера больше не меняется от сервера к серверу для одного и того же файла, и поэтому рекомендации Yahoo больше не применяются.

Поскольку на самом деле вы не можете подавить заголовок ETag в IIS7, вероятно, лучше вообще не возиться с ним. Я обнаружил, что наиболее полезным правилом конфигурации является «Если по умолчанию что-то не ломается, оставьте это в покое».

ЭнтониУДжонс
источник
2
У меня есть соблазн убить etags по другой причине: если я не понимаю, я вижу, что IIS на одном сервере безвозмездно меняет первый компонент etags (то есть так называемую "Filetimestamp"), несмотря на то, что мой файл не изменен. Например, последняя версия файла будет в браузере, браузер отправит 'If-None-Match: "01cc3a8acccc1: 0"' / 'If-Modified-Since: Fri, 06 Jan 2012 00:32: 24 GMT ', и IIS ответит' ETag: "b6baeea8acccc1: 0" '/' Last-Modified: Fri, 06 Jan 2012 00:32:24 GMT '. Это файлы js с URL-адресами, например foo.js? Rev = xxx, каждый раз передавая один и тот же xxx.
Крис
@Chris: Я делаю почти то же самое, я разрешаю кэшировать файлы js и меняю только xxx при изменении файла. Я не могу сказать, что когда-либо сталкивался с поведением, которое вы наблюдаете в любой версии IIS. Я подозреваю, что что-то не так с вашей конфигурацией IIS.
AnthonyWJones 06
Благодарю. Насколько вам известно, основывается ли часть etags "Filetimestamp" ТОЛЬКО на отметке времени запрашиваемого файла, а не на чем-либо, связанном с состоянием машины / процесса / приложения?
Крис
@Chris: Насколько я знаю, да, E-Tag основан только на времени файла. Я пробовал возиться со своим сервером, но не могу воспроизвести проблему, которую вы видите.
AnthonyWJones
Я не знаю, что сделать сервер немодифицируемым - это разумная политика. Помимо. Я тестирую Expires в далеком будущем, и мне просто не нужен ответ HTTP 304 - никогда. Я хочу, чтобы вещи оставались в кеше в течение долгого времени, поскольку я знаю, что эти активы редко меняются. Существует множество документации IETF, включая спецификацию HTTP RFC 2616, в которой объясняется, что это можно и нужно делать как администратор сайта, поскольку этот человек будет знать свою ситуацию намного лучше. Разработчики всегда ищут то, что происходит в «дикой природе».
Джош Робинсон
33

Вы могли подумать, что если сделать это в файле web.config, это поможет отключить ETags в IIS7. Но трассировка сниффера подтверждает, что ETag все равно отправляется.

<httpProtocol>
    <customHeaders>
        <remove name="ETag" />
    </customHeaders>
</httpProtocol>

Использование бланка тоже не работает. ETag все равно отправляется.

<httpProtocol>
    <customHeaders>
        <add name="ETag" value="" />
    </customHeaders>
</httpProtocol>

Установка ETag на пустые кавычки, как предлагали другие сайты, не работает.

<httpProtocol>
    <customHeaders>
        <add name="ETag" value="&quot;&quot;" />
    </customHeaders>
</httpProtocol>

Вызывает еще большее количество сообщений ETag:

ETag: "8ee1ce1acf18ca1: 0", ""

В заключение, я ничего не могу попробовать или придумать, чтобы убить ETag на IIS7, по крайней мере, без написания пользовательских модулей и т. Д.

Джефф Этвуд
источник
2
Я не подтверждал это, Джефф, но могло ли это быть потому, что раздел httpProtocol заблокирован на уровне веб-сайта. Я обнаружил, что это тот случай, когда я пытался программно установить уровень сжатия iis7 через файл web.config. Мне пришлось наконец разблокировать этот раздел на уровне корневого сервера. Может в этом разделе такая же проблема? (Мне бы очень хотелось, чтобы ВСЕ настройки IIS были доступны через графический интерфейс)
Pure.Krome
1
@ Pure.Krome: Разблокировка в сочетании со второй попыткой Джеффа, описанной выше, кажется, работает для меня в большинстве случаев ... кроме (конечно!) Содержимого изображений. : - \ <sectionGroup name = "system.webServer"> <section name = "httpProtocol" overrideModeDefault = "Allow" /> </sectionGroup> [...] <httpProtocol> <customHeaders> <clear /> <add name = "ETag" value = "" /> </customHeaders> </httpProtocol> Итак, по крайней мере, здесь есть частичное решение.
jerhewet 08
@jer, вы должны добавить это как правильный ответ
Джефф Этвуд
1
@jerhewet у меня не работает (Windows Server 2008 R2, IIS 7.5)
sinelaw
1
Там, где все другие решения не удавались или были невозможны для меня, работало простое правило перезаписи. См. Мой ответ: stackoverflow.com/a/18025228/705198
AndrewPK 02
22

Я написал специальный модуль http, чтобы справиться с этим. Это действительно не так плохо, как кажется. Вот код:

using System;
using System.Web;

namespace StrongNamespace.HttpModules
{
    public class CustomHeaderModule : IHttpModule
    {
        public void Init(HttpApplication application)
        {
            application.PostReleaseRequestState += new EventHandler(application_PostReleaseRequestState);

        }

        public void Dispose()
        {
        }

        void application_PostReleaseRequestState(object sender, EventArgs e)
        {
            HttpContext.Current.Response.Headers.Remove("Server");
            HttpContext.Current.Response.Headers.Remove("X-AspNet-Version");
            HttpContext.Current.Response.Headers.Remove("ETag");
        }
    }
}

Вот необходимые вам изменения в web.config:

<configuration>
    <system.webServer>
        <httpProtocol>
            <customHeaders>
                <remove name="X-Powered-By"/>
            </customHeaders>
        </httpProtocol>
        <modules>
            <add name="CustomHeaderModule" type="StrongNamespace.HttpModules.CustomHeaderModule"/>
        </modules>
    </system.webServer>
</configuration>
Дэн
источник
1
+1, однако, похоже, это касается только ресурсов, запрашиваемых у веб-сайта, а не таких вещей, как значки,
Брэд
13

Я понимаю, что это старый вопрос, но я столкнулся с ним, когда искал решение. Я думаю, что нашел разумный ответ на этот вопрос .

Натан Фокс
источник
подтверждено, что работает, пока вы очищаете кеш после его изменения;)
peter3
7

У нас была эта проблема, и даже установка пустого пользовательского заголовка ETag в IIS 7 не работала для всех файлов (например, файлов изображений). В итоге мы создали HttpModule, который явно удаляет заголовок ETag.

Джванагель
источник
6

ОБНОВЛЕНИЕ: добавлено требование к модулю перезаписи URL благодаря пользователю @ChrisBarr

В iis 6 это просто, вы можете добавить собственный заголовок для 'ETag' = ""

В IIS 7, прочитав эту ветку и поняв, что это невозможно без использования настраиваемого модуля http, я обнаружил, что вы можете просто установить модуль Microsoft URL Rewrite и добавить правило перезаписи исходящего трафика следующим образом:

<outboundRules>
  <rule name="Remove ETag">
    <match serverVariable="RESPONSE_ETag" pattern=".+" />
    <action type="Rewrite" value="" />
  </rule>
</outboundRules>

Это действительно работает, и вам не нужен специальный модуль http (dll). Разблокировка раздела конфигурации system.webServer и установка customHeaders и т. Д. Не работает - по крайней мере, во всех случаях, которые я пробовал. Простое исходящее правило перезаписи делает.

АндрейПК
источник
1
Это решение требует, чтобы этот настраиваемый модуль был установлен в IIS, верно?
CBarr
@ChrisBarr Да, это так - извините, я не упомянул об этом. Ответ обновлен.
AndrewPK
4

Кстати при использовании iis8 все просто

<element name="clientCache">
   <attribute name="cacheControlMode" type="enum" defaultValue="NoControl">
          <enum name="NoControl" value="0" />
          <enum name="DisableCache" value="1" />
          <enum name="UseMaxAge" value="2" />
          <enum name="UseExpires" value="3" />
  </attribute>
  <attribute name="cacheControlMaxAge" type="timeSpan" defaultValue="1.00:00:00" />
  <attribute name="httpExpires" type="string" />
  <attribute name="cacheControlCustom" type="string" />
  <attribute name="setEtag" type="bool" defaultValue="true" />
</element>

IIS 8.0: использовать или не использовать ETag

JeffZhnn
источник
2

http://www.jesscoburn.com/archives/2008/10/02/quickly-configure-or-disable-etags-in-iis7-or-iis6/ имеет хорошее иллюстрированное руководство.

По сути, вы создаете настраиваемый заголовок ответа с именем ETag и делаете его значение пустым.

Серен Куклау
источник
В IIS6 это сработало для меня только тогда, когда я не установил значение, а не только две двойные кавычки. т.е. <httpProtocol> <customHeaders> <add name = "ETag" value = "" /> </customHeaders> </httpProtocol>
Дункан,
2

Ознакомьтесь с этим сообщением в блоге о том, как полностью удалить http-заголовок Etag в iis6, iis7 и iis7.5

http://lightspeednow.com/blog/2010/05/21/iis-tutorial-how-to-completely-remove-etags-entity-tags-from-iis6-iis7-and-iis7-5/

Брайан
источник
2
Для этого требуется сторонний плагин под названием Helicon Ape. На самом деле нам нужно решение, в котором используется собственная конфигурация IIS, а не дополнительный плагин. Это особенно актуально для любой крупномасштабной веб-фермы, где именно ETag является самой большой проблемой.
Кейт
1

В IIS 7 вам больше не нужно беспокоиться об etags, поскольку номер конфигурации IIS всегда равен 0.

Проблема все еще существует, если у вас есть веб-серверы IIS6 и IIS7 в одной ферме. В этом случае вам придется вручную установить номер конфигурации IIS6 на 0, как описано в этой статье .

Etags на самом деле очень полезны, поскольку вам не нужно менять имя файла, как это делает переполнение стека (например, default.css? 1234). Если вы измените файл default.css, он изменит etag, и поэтому последующие запросы будут получать файл с сервера, а не из кеша.

Alex
источник
7
слишком большие даты истечения срока действия делают ETags неактуальными, поскольку браузер буквально никогда не будет запрашивать файл снова до указанной даты (или, конечно, до тех пор, пока имя файла не изменится). Таким образом, необходимость его удаления - в этом сценарии устарела.
Джефф Этвуд,
3
@JeffAtwood не совсем верно, браузер запросит файл, если пользователь нажмет кнопку обновления, если etag такой же, вы получите 304, если diff вы получите 200, проблема здесь в том, что вы отправляете 2 заголовка, где 1 будет было достаточно
Сэм Саффрон
1

Я думаю, это сработает .. Я знаю, что удалить и пустить не получится.

    <configuration>
     <system.webServer>
       <httpProtocol>
          <customHeaders>
            <add name="ETag" value=" " /> 
          </customHeaders>
        </httpProtocol>
       </configuration>
     </system.webServer>
Мкр. Алим Уль Карим
источник