Jak usunąć nagłówki eTag z usług IIS7?

83

Zgodnie z najlepszymi praktykami Yahoo dla wysokowydajnych witryn internetowych , chciałbym usunąć Etags z moich nagłówków (ręcznie zarządzam całym moim buforowaniem i nie potrzebuję Etags ... i kiedy / jeśli muszę skalować do farmy, Naprawdę chciałbym, żeby odeszli). Używam usług IIS7 w systemie Windows Server 2008. Czy ktoś wie, jak mogę to zrobić?

Jeff Atwood
źródło
Działa z IIS 8.0 i nowszymi wersjami co najmniej tak, jak pokazano w drugiej odpowiedzi tego postu: stackoverflow.com/questions/7947420/ ...
RBT

Odpowiedzi:

39

W IIS7 numer zmiany Etag (część następującego Etag:) jest zawsze ustawiony na 0.

W związku z tym Etag z serwera nie różni się już od serwera do serwera dla tego samego pliku, a zatem najlepsza praktyka Yahoo nie ma już zastosowania.

Ponieważ w rzeczywistości nie można zablokować nagłówka ETag w IIS7, prawdopodobnie najlepiej byłoby nie majstrować przy nim w ogóle. Odkryłem, że najbardziej użyteczną regułą konfiguracji jest „Jeśli domyślna reguła czegoś nie psuje, zostaw ją w spokoju”.

AnthonyWJones
źródło
2
Kusi mnie, aby zabić etags z innego powodu: jeśli nie rozumiem rzeczy, widzę, że usługi IIS na jednym serwerze nieodpłatnie zmieniają pierwszy składnik etagów (tj. Tak zwany „Filetimestamp”), mimo że mój plik nie jest zmodyfikowany. Na przykład najnowsza wersja pliku będzie w przeglądarce, przeglądarka wyśle ​​„If-None-Match:” 01cc3a8acccc1: 0 ”'/' If-Modified-Since: Fri, 06 Jan 2012 00:32: 24 GMT ', a usługi IIS odpowiedzą „ETag:" b6baeea8acccc1: 0 "" / "Last-Modified: Fri, 06 Jan 2012 00:32:24 GMT”. Są to pliki js z adresami URL, takie jak foo.js? Rev = xxx, za każdym razem przekazujące te same xxx.
Chris,
@Chris: Robię prawie to samo, pozwalam na buforowanie plików js i zmieniam xxx tylko wtedy, gdy plik jest zmieniany. Nie mogę powiedzieć, że kiedykolwiek spotkałem się z zachowaniem, które widzisz w dowolnej wersji usług IIS. Coś jest trochę dziwne z twoją konfiguracją IIS, jak podejrzewam.
AnthonyWJones,
Dzięki. O ile wiesz, czy część „Filetimestamp” etagów jest oparta TYLKO na sygnaturze czasowej żądanego pliku, a nie na jakichkolwiek informacjach o stanie maszyny / procesu / aplikacji?
Chris,
@Chris: O ile wiem, tak E-Tag jest oparty tylko na czasie pliku. Próbowałem bawić się moim serwerem i nie mogę odtworzyć problemu, który widzisz.
AnthonyWJones,
Nie wiem, czy uczynienie serwera niemodyfikowalnym jest mądrą polityką. Oprócz. Testuję Expires w dalekiej przyszłości i po prostu nie chcę odpowiedzi HTTP 304 - nigdy. Chcę, aby rzeczy pozostawały w pamięci podręcznej przez dłuuuugi czas, ponieważ wiem, że te aktywa rzadko się zmieniają. Istnieje wiele dokumentacji IETF, w tym specyfikacja HTTP RFC 2616, która wyjaśnia, że ​​można i należy to zrobić jako administrator witryny, ponieważ ta osoba będzie znacznie lepiej znać swoją sytuację. Realizatorzy zawsze szukają tego, co dzieje się na „dziko”.
Josh Robinson
33

Można by pomyśleć, że zrobienie tego w pliku web.config działałoby w celu wyłączenia ETagów w IIS7. Ale ślad sniffera potwierdza, że ​​ETag i tak został wysłany.

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

Używanie pustego miejsca też nie działa. ETag i tak jest wysyłany.

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

Ustawienie ETag na puste cudzysłowy, jak sugerowały inne witryny, nie działa.

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

Powoduje wysłanie jeszcze większej liczby ETagów:

ETag: "8ee1ce1acf18ca1: 0", ""

Podsumowując, nic nie mogę wypróbować ani wymyślić, aby zabić ETag w IIS7, przynajmniej bez pisania niestandardowych modułów itp.

Jeff Atwood
źródło
2
Nie potwierdziłem tego, Jeff, ale może to być spowodowane tym, że sekcja httpProtocol jest zablokowana na poziomie witryny. Znalazłem taki przypadek, gdy próbowałem programowo ustawić poziom kompresji iis7 za pośrednictwem pliku web.config. Musiałem w końcu odblokować tę sekcję na poziomie serwera głównego. Może ta sekcja ma ten sam problem? (Naprawdę chciałbym, żeby WSZYSTKIE ustawienia IIS były dostępne za pośrednictwem GUI)
Pure.Krome
1
@ Pure.Krome: Odblokowanie w połączeniu z drugą próbą Jeffa powyżej wydaje się działać dla mnie w większości przypadków ... z wyjątkiem (oczywiście!) Treści graficznych. : - \ <sectionGroup name = "system.webServer"> <section name = "httpProtocol" overrideModeDefault = "Allow" /> </sectionGroup> [...] <httpProtocol> <customHeaders> <clear /> <add name = "ETag" value = "" /> </customHeaders> </httpProtocol> Więc przynajmniej wydaje się, że jest tutaj częściowe rozwiązanie.
jerhewet,
@jer należy dodać, że jako poprawną odpowiedź
Jeff Atwood
1
@jerhewet nie działa dla mnie (Windows Server 2008 R2, IIS 7.5)
sinelaw
1
Tam, gdzie wszystkie inne rozwiązania zawiodły lub były niewykonalne do wdrożenia dla mnie, działała prosta reguła przepisywania. Zobacz moją odpowiedź: stackoverflow.com/a/18025228/705198
AndrewPK,
22

Napisałem niestandardowy moduł http do obsługi tego. Naprawdę nie jest tak źle, jak się wydaje. Oto kod:

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");
        }
    }
}

Oto zmiany w pliku web.config, które chcesz:

<configuration>
    <system.webServer>
        <httpProtocol>
            <customHeaders>
                <remove name="X-Powered-By"/>
            </customHeaders>
        </httpProtocol>
        <modules>
            <add name="CustomHeaderModule" type="StrongNamespace.HttpModules.CustomHeaderModule"/>
        </modules>
    </system.webServer>
</configuration>
Dan
źródło
1
+1, jednak wydaje się, że dotyczy to tylko zasobów poproszonych o witrynę, a nie rzeczy takich jak favikony
Brad
13

Zdaję sobie sprawę, że to stare pytanie, ale natknąłem się na nie, szukając rozwiązania. Myślę, że znalazłem rozsądną odpowiedź, którą zamieściłem na to pytanie .

Nathan Fox
źródło
potwierdzono, że działa tak długo, jak wyczyścisz pamięć podręczną po jej zmianie;)
peter3 11.11
7

Mieliśmy ten problem i nawet ustawienie pustego niestandardowego nagłówka ETag w IIS 7 nie działało dla wszystkich plików (na przykład plików obrazów). Skończyło się na utworzeniu HttpModule, który jawnie usuwa nagłówek ETag.

jwanagel
źródło
6

AKTUALIZACJA: dodano wymagania dotyczące modułu przepisywania adresów URL dzięki użytkownikowi @ChrisBarr

W iis 6 jest to łatwe, możesz dodać niestandardowy nagłówek dla 'ETag' = ""

W IIS 7, po przeczytaniu tego wątku i stwierdzeniu, że jest to niemożliwe bez użycia niestandardowego modułu http, stwierdziłem, że można po prostu zainstalować moduł ponownego zapisywania adresów URL firmy Microsoft i dodać następującą regułę przepisywania ruchu wychodzącego:

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

To faktycznie działa i nie potrzebujesz niestandardowego modułu http (dll). Odblokowanie sekcji konfiguracyjnej system.webServer i ustawienie customHeaders itp. Nie działa - przynajmniej we wszystkich przypadkach, które próbowałem. Robi to prosta reguła przepisywania ruchu wychodzącego.

AndrewPK
źródło
1
To rozwiązanie wymaga jednak zainstalowania tego niestandardowego modułu w usługach IIS, prawda?
CBarr
@ChrisBarr tak - przepraszam, że nie wspomniałem o tym. Zaktualizowano odpowiedź.
AndrewPK,
4

Nawiasem mówiąc, kiedy używasz iis8, jest to proste

<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: Aby używać lub nie używać ETag

JeffZhnn
źródło
2

http://www.jesscoburn.com/archives/2008/10/02/quickly-configure-or-disable-etags-in-iis7-or-iis6/ ma ładny przewodnik obrazkowy.

Zasadniczo tworzysz niestandardowy nagłówek odpowiedzi o nazwie ETag i ustawiasz jego wartość jako pustą.

Sören Kuklau
źródło
W IIS6 działało to tylko wtedy, gdy nie ustawiłem żadnej wartości, a nie tylko dwa podwójne cudzysłowy. tj. <httpProtocol> <customHeaders> <add name = "ETag" value = "" /> </customHeaders> </httpProtocol>
Duncan
2

Sprawdź ten wpis na blogu, jak całkowicie usunąć nagłówek HTTP Etag w iis6, iis7 i iis7.5

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

Brian
źródło
2
Wymaga to wtyczki innej firmy o nazwie Helicon Ape. Naprawdę potrzebujemy rozwiązania, które używa natywnej konfiguracji IIS, a nie dodatkowej wtyczki. Jest to szczególnie prawdziwe w przypadku dowolnej farmy internetowej na dużą skalę, w której właśnie ETag jest największym problemem.
Keith,
1

W IIS 7 nie powinieneś już martwić się o etags, ponieważ numer konfiguracji IIS jest zawsze ustawiony na 0.

Nadal występuje problem, jeśli masz serwery sieciowe IIS6 i IIS7 w tej samej farmie. W takim przypadku należałoby ręcznie ustawić numer konfiguracji usług IIS6 na 0, zgodnie z opisem w tym artykule .

Etykiety są w rzeczywistości bardzo przydatne, ponieważ nie musisz zmieniać nazwy pliku, tak jak robi to przepełnienie stosu (tj. Default.css? 1234). Jeśli zmienisz plik default.css, zmieni to etag i dlatego kolejne żądania będą pobierać plik z serwera, a nie z pamięci podręcznej.

Alex
źródło
7
Bardzo odległe daty wygaśnięcia sprawiają, że znaczniki ETag są nieistotne, ponieważ przeglądarka dosłownie nigdy nie zażąda ponownie pliku do określonej daty (lub oczywiście do momentu zmiany nazwy pliku). Zatem potrzeba jego usunięcia - jest przestarzała w tym scenariuszu.
Jeff Atwood
3
@JeffAtwood nie do końca prawda, przeglądarka zażąda pliku, jeśli użytkownik naciśnie przycisk odświeżania, jeśli etag jest taki sam, otrzymasz 304, jeśli otrzymasz 200, problem polega na tym, że wyślesz 2 nagłówki, gdzie 1 wystarczyło
Sam Saffron
1

Myślę, że to zadziała ... Wiem, że usuwanie i puste nie działa.

    <configuration>
     <system.webServer>
       <httpProtocol>
          <customHeaders>
            <add name="ETag" value=" " /> 
          </customHeaders>
        </httpProtocol>
       </configuration>
     </system.webServer>
Md. Alim Ul Karim
źródło