Wie entferne ich eTag-Header aus IIS7?

83

Per Best Practices Yahoo für Websites High Performance Web , ich möchte Etags von meinem Header entfernen (ich alle meine Caching manuell bin Verwaltung und keine Notwendigkeit für Etags haben ... und wenn / wenn ich auf einer Farm Skala benötigen, Ich würde sie wirklich gerne weg haben. Ich verwende IIS7 unter Windows Server 2008. Weiß jemand, wie ich das tun kann?

Jeff Atwood
quelle
Es funktioniert ab IIS 8.0 mindestens wie in der zweiten Antwort dieses Beitrags gezeigt: stackoverflow.com/questions/7947420/…
RBT

Antworten:

39

Unter IIS7 wird die Etag-Änderungsnummer (der folgende Teil des Etag :) immer auf 0 gesetzt.

Daher variiert der Etag vom Server nicht mehr von Server zu Server für dieselbe Datei, und daher gilt die bewährte Methode von Yahoo nicht mehr wirklich.

Da Sie den ETag-Header auf IIS7 nicht wirklich unterdrücken können, ist es wahrscheinlich am besten, wenn Sie überhaupt nicht damit herumspielen. Ich habe festgestellt, dass die mit Abstand nützlichste Konfigurationsregel lautet: "Wenn die Standardeinstellung etwas nicht beschädigt, lassen Sie es in Ruhe".

AnthonyWJones
quelle
2
Ich bin versucht, Etags aus einem anderen Grund zu töten: Wenn ich Dinge nicht falsch wahrnehme, sehe ich, dass IIS auf einem einzelnen Server die erste Komponente von Etags (dh den sogenannten "Filetimestamp") unentgeltlich ändert, obwohl meine Datei nicht vorhanden ist geändert. Die neueste Version einer Datei befindet sich beispielsweise im Browser. Der Browser sendet "If-None-Match:" 01cc3a8acccc1: 0 "/" If-Modified-Since: Fr, 06 Jan 2012 00:32: 24 GMT 'und IIS antworten mit' ETag: "b6baeea8acccc1: 0" '/' Zuletzt geändert: Fr, 06. Januar 2012 00:32:24 GMT '. Dies sind js-Dateien mit URLs wie foo.js? Rev = xxx, die jedes Mal dasselbe xxx übergeben.
Chris
@Chris: Ich mache fast das Gleiche, ich erlaube das Zwischenspeichern von js-Dateien und ändere das xxx nur, wenn die Datei geändert wird. Ich kann nicht sagen, dass ich jemals auf das Verhalten gestoßen bin, das Sie auf einer Version von IIS sehen. Ich vermute, dass etwas mit Ihrer IIS-Konfiguration etwas seltsam ist.
AnthonyWJones
Vielen Dank. Soweit Sie wissen, basiert der Teil "Filetimestamp" von etags NUR auf dem Zeitstempel der angeforderten Datei und nicht auf dem Status der Maschine / des Prozesses / der Anwendung?
Chris
@ Chris: Soweit ich weiß, basiert E-Tag nur auf der Dateizeit. Ich habe versucht, mit meinem Server herumzuspielen, und ich kann das angezeigte Problem nicht reproduzieren.
AnthonyWJones
Ich weiß nicht, dass es sinnvoll ist, einen Server nicht modifizierbar zu machen. Außerdem. Ich teste Expires für die ferne Zukunft und möchte einfach keine HTTP 304-Antwort - niemals. Ich möchte, dass die Dinge für eine lange Zeit in einem Cache bleiben, da ich weiß, dass sich diese Assets selten ändern. Es gibt viele IETF-Dokumentationen, einschließlich der HTTP-Spezifikation RFC 2616, die erklärt, dass dies als Site-Administrator durchgeführt werden kann und sollte, da diese Person ihre Situation weitaus besser kennt. Implementierer sind immer auf der Suche nach dem, was in der "Wildnis" passiert.
Josh Robinson
33

Sie würden denken, dass dies in der web.config funktioniert, um ETags in IIS7 zu deaktivieren. Die Sniffer-Ablaufverfolgung bestätigt jedoch, dass ETag trotzdem gesendet wird.

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

Die Verwendung von blank funktioniert auch nicht. ETag wird trotzdem runtergeschickt.

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

Das Setzen des ETag auf leere Anführungszeichen, wie von anderen Websites vorgeschlagen, funktioniert nicht.

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

Bewirkt, dass noch mehr ETag gesendet werden:

ETag: 8ee1ce1acf18ca1: 0,

Zusammenfassend lässt sich sagen, dass nichts, was ich versuchen oder mir vorstellen kann, funktioniert, um ETag auf IIS7 zu beenden, zumindest ohne benutzerdefinierte Module usw. zu schreiben.

Jeff Atwood
quelle
2
Ich habe diesen Jeff nicht bestätigt, aber dies könnte daran liegen, dass der Abschnitt httpProtocol auf Website-Ebene gesperrt ist. Ich fand dies der Fall, als ich versuchte, die iis7- Komprimierungsstufe über die Datei web.config programmgesteuert einzustellen . Ich musste diesen Abschnitt endlich auf der Root-Server-Ebene entsperren . Vielleicht hat dieser Abschnitt das gleiche Problem? (Ich wünschte wirklich, ALLE IIS-Einstellungen
wären
1
@ Pure.Krome: Das Entsperren, kombiniert mit Jeffs zweitem Versuch oben, scheint in den meisten Fällen für mich zu funktionieren ... außer (natürlich!) Für Bildinhalte. : - \ <sectionGroup name = "system.webServer"> <section name = "httpProtocol" overrideModeDefault = "Allow" /> </ sectionGroup> [...] <httpProtocol> <customHeaders> <clear /> <add name = "ETag" value = "" /> </ customHeaders> </ htpProtocol> Zumindest scheint es hier eine Teillösung zu geben .
Jerhewet
@jer sollten Sie das als richtige Antwort hinzufügen
Jeff Atwood
1
@ Jerhewet funktioniert nicht für mich (Windows Server 2008 R2, IIS 7.5)
Sinelaw
1
Wo alle anderen Lösungen fehlschlugen oder für mich nicht realisierbar waren, funktionierte eine einfache Umschreiberegel. Siehe meine Antwort: stackoverflow.com/a/18025228/705198
AndrewPK
22

Ich habe ein benutzerdefiniertes http-Modul geschrieben, um dies zu handhaben. Es ist wirklich nicht so schlimm, wie es sich anhört. Hier ist der Code:

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

Hier sind die gewünschten Änderungen an 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>
Dan
quelle
1
+1, dies scheint jedoch nur die von der Website angeforderten Ressourcen abzudecken, nicht Dinge wie Favicons
Brad
13

Mir ist klar, dass dies eine alte Frage ist, aber ich bin auf sie gestoßen, als ich nach einer Lösung gesucht habe. Ich glaube, ich habe eine vernünftige Antwort gefunden, die ich auf diese Frage gepostet habe .

Nathan Fox
quelle
bestätigt zu arbeiten, solange Sie Ihren Cache nach dem Ändern
leeren
7

Wir hatten dieses Problem, und selbst das Festlegen eines leeren benutzerdefinierten ETag-Headers in IIS 7 funktionierte nicht für alle Dateien (z. B. Bilddateien). Am Ende haben wir ein HttpModule erstellt, das den ETag-Header explizit entfernt.

jwanagel
quelle
6

UPDATE: URL Rewrite Module-Anforderung dank Benutzer @ChrisBarr hinzugefügt

In iis 6 können Sie ganz einfach einen benutzerdefinierten Header für 'ETag' = "" hinzufügen.

In IIS 7 stellte ich nach dem Lesen dieses Threads und der Feststellung, dass dies ohne die Verwendung eines benutzerdefinierten http-Moduls nicht möglich ist, fest, dass Sie das URL-Rewrite-Modul von Microsoft einfach installieren und eine ausgehende Rewrite-Regel wie folgt hinzufügen können:

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

Dies funktioniert tatsächlich und Sie benötigen kein benutzerdefiniertes http-Modul (DLL). Das Entsperren des Konfigurationsabschnitts system.webServer und das Festlegen von customHeaders usw. funktioniert nicht - zumindest in allen Fällen, die ich versucht habe. Eine einfache ausgehende Umschreibregel funktioniert.

AndrewPK
quelle
1
Für diese Lösung muss dieses benutzerdefinierte Modul jedoch in IIS installiert sein. Richtig?
CBarr
@ ChrisBarr ja, das tut es - sorry, das habe ich nicht erwähnt. Antwort aktualisiert.
AndrewPK
4

Übrigens, wenn Sie iis8 verwenden, ist es einfach

<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 verwenden oder nicht verwenden

JeffZhnn
quelle
2

http://www.jesscoburn.com/archives/2008/10/02/quickly-configure-or-disable-etags-in-iis7-or-iis6/ hat eine schöne Bildanleitung.

Im Wesentlichen erstellen Sie einen benutzerdefinierten Antwortheader mit dem Namen ETag und machen dessen Wert leer.

Sören Kuklau
quelle
Unter IIS6 funktionierte dies nur, wenn ich keinen Wert festlegte, nicht nur zwei doppelte Anführungszeichen. dh <httpProtocol> <customHeaders> <add name = "ETag" value = "" /> </ customHeaders> </ htpProtocol>
Duncan
2

In diesem Blogbeitrag erfahren Sie, wie Sie den Etag-http-Header in iis6, iis7 und iis7.5 vollständig entfernen

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

Brian
quelle
2
Dies erfordert ein Plug-In eines Drittanbieters namens Helicon Ape. Wir brauchen wirklich eine Lösung, die die native IIS-Konfiguration verwendet, kein zusätzliches Plug-In. Dies gilt insbesondere für jede große Webfarm, in der genau das ETag das größte Problem darstellt.
Keith
1

In IIS 7 sollten Sie sich keine Gedanken mehr über Etags machen müssen, da die IIS-Konfigurationsnummer immer auf 0 gesetzt ist.

Es gibt immer noch ein Problem, wenn Sie IIS6- und IIS7-Webserver in derselben Farm haben. In diesem Fall müssten Sie die IIS6-Konfigurationsnummer manuell auf 0 setzen, wie in diesem Artikel beschrieben .

Etags sind tatsächlich sehr nützlich, da Sie den Dateinamen nicht wie beim Stapelüberlauf ändern müssen (z. B. default.css? 1234). Wenn Sie die Datei default.css ändern, wird das etag geändert, und nachfolgende Anforderungen erhalten die Datei vom Server und nicht vom Cache.

Alex
quelle
7
Weit entfernte Ablaufdaten machen ETags irrelevant, da der Browser die Datei buchstäblich nie wieder anfordert, bis das angegebene Datum (oder bis sich der Dateiname natürlich ändert). Daher ist die Notwendigkeit, sie zu entfernen, in diesem Szenario veraltet.
Jeff Atwood
3
@JeffAtwood nicht unbedingt wahr, der Browser fordert die Datei an, wenn der Benutzer auf die Schaltfläche "Aktualisieren" klickt. Wenn der etag derselbe ist, erhalten Sie eine 304, wenn diff eine 200 erhält. Das Problem hierbei ist, dass Sie 2 Header senden, wo 1 würde waren genug
Sam Saffron
1

Ich denke, das wird funktionieren. Ich weiß, entfernen und leer funktioniert nicht.

    <configuration>
     <system.webServer>
       <httpProtocol>
          <customHeaders>
            <add name="ETag" value=" " /> 
          </customHeaders>
        </httpProtocol>
       </configuration>
     </system.webServer>
Md. Alim Ul Karim
quelle