Ich habe ein seltsames Problem mit IIS 7.
Manchmal scheint es eine 304 anstelle einer 200 zurückzugeben.
Hier ist eine Beispielanforderung, die mit Fiddler erfasst wurde:
(Beachten Sie, dass sich die angeforderte Datei noch nicht im Cache meines Browsers befindet.)
GET https://[mysite]/Content/js/jquery.form.js HTTP/1.1 Accept: */* Referer: https://[mysite]/Welcome/News Accept-Language: sv-SE User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; .NET4.0C; .NET4.0E) Accept-Encoding: gzip, deflate Host: [mysite] Connection: Keep-Alive Cache-Control: no-cache Cookie: ...
Beachten Sie, dass die Anforderung kein If-Modified-Since oder If-None-Match enthält.
Trotzdem lautet die Antwort:
HTTP/1.1 304 Not Modified Cache-Control: public Expires: Tue, 02 Mar 2010 06:26:08 GMT Last-Modified: Mon, 22 Feb 2010 21:58:44 GMT ETag: "1CAB40A337D4200" Server: Microsoft-IIS/7.5 X-Powered-By: ASP.NET Date: Mon, 01 Mar 2010 17:06:34 GMT
Hat jemand eine Ahnung, was hier falsch sein könnte?
Ich verwende IIS 7 unter Windows Web Server 2008 R2.
BEARBEITEN:
Ich habe eine Problemumgehung gefunden, das Caching aktiviert und dann auf Erweiterungsebene deaktiviert. Das hat den Trick für mich getan.
<configuration>
<system.webServer>
<caching enabled="true" enableKernelCache="true">
<profiles>
<add extension=".png" policy="DisableCache" kernelCachePolicy="DisableCache" />
<add extension=".gif" policy="DisableCache" kernelCachePolicy="DisableCache" />
<add extension=".js" policy="DisableCache" kernelCachePolicy="DisableCache" />
<add extension=".css" policy="DisableCache" kernelCachePolicy="DisableCache" />
</profiles>
</caching>
<staticContent>
<clientCache cacheControlMode="NoControl" />
</staticContent>
</system.webServer>
</configuration>
windows-server-2008
iis-7
asp.net
Ola Herrdahl
quelle
quelle
Antworten:
Gemäß Abschnitt 14.9 der HTTP1.1-Spezifikation kann die
no-cache
Direktive für den Cache-Control-Header nur vom Ursprungsserver festgelegt werden. Dies bedeutet, dass IIS den Header in Ihrer Anforderung ignoriert.Abschnitt 14.9.1 definiert
public
,private
undno-cache
wie in den Richtlinien zu beschränken , was zwischenspeicherbar ist, die nur durch den Server gestellt werden.Wenn Sie nicht möchten, dass Ihre .js-Datei zwischengespeichert wird, müssen Sie entweder die
no-cache
Direktive in der App festlegen (dh den ASP.NET-Code) oder denCache-Control
Header in der Anforderung ändern , um dieno-store
Direktive zu verwenden stattno-cache
.EDIT:
Basierend auf Ihrem Kommentar - ja, ich nahm an, dass Sie nicht wollten, dass die Datei zwischengespeichert wird. Der 304 könnte dann als Ergebnis der Datei in einem der internen Caches von IIS kommen. Schauen Sie sich diese an:
quelle
Ich habe seit einiger Zeit das gleiche Problem und habe das gesamte Caching deaktiviert ... Ich habe jedoch irgendwann das Komprimierungsmodul für IIS7 installiert, das standardmäßig die Komprimierung statischer Dateien auf meinen vorhandenen Sites aktiviert hatte. Ich habe die Komprimierung für die betroffenen Stellen deaktiviert und jetzt scheinen sie feines Holz zu bearbeiten .
quelle
Dieser Fehler trat ebenfalls auf, wir verwendeten jedoch eine Asset Management-Bibliothek (Kassette). Nach einer umfassenden Untersuchung dieses Problems haben wir festgestellt, dass die Hauptursache für dieses Problem in einer Kombination aus ASP.NET, IIS und Kassette liegt. Ich bin nicht sicher, ob dies Ihr Problem ist (Verwendung der
Headers
API anstelle derCache
API), aber das Muster scheint dasselbe zu sein.Fehler Nr. 1
Cassette setzt den
Vary: Accept-Encoding
Header als Teil seiner Antwort auf ein Bundle, da er den Inhalt mit gzip / deflate codieren kann:Der ASP.NET-Ausgabecache gibt jedoch immer die Antwort zurück, die zuerst zwischengespeichert wurde. Wenn beispielsweise die erste Anforderung hat
Accept-Encoding: gzip
und Kassette komprimierten Inhalt zurückgibt, speichert der ASP.NET-Ausgabecache die URL alsContent-Encoding: gzip
. Die nächste Anforderung an dieselbe URL, jedoch mit einer anderen akzeptablen Codierung (z. B.Accept-Encoding: deflate
), gibt die zwischengespeicherte Antwort mit zurückContent-Encoding: gzip
.Dieser Fehler wird dadurch verursacht, dass Cassette die
HttpResponseBase.Cache
API verwendet, um die Einstellungen für den Ausgabecache festzulegen (z. B.Cache-Control: public
), aber dieHttpResponseBase.Headers
API verwendet, um denVary: Accept-Encoding
Header festzulegen. Das Problem ist , dass die ASP.NETOutputCacheModule
ist nicht bewusst , Response - Header; Es funktioniert nur über dieCache
API. Das heißt, es wird erwartet, dass der Entwickler eine unsichtbar eng gekoppelte API verwendet und nicht nur Standard-HTTP.Fehler # 2
Bei Verwendung von IIS 7.5 (Windows Server 2008 R2) kann Fehler 1 ein separates Problem mit dem IIS-Kernel und den Benutzercaches verursachen. Wenn ein Bundle beispielsweise erfolgreich zwischengespeichert wurde
Content-Encoding: gzip
, kann es im IIS-Kernel-Cache mit angezeigt werdennetsh http show cachestate
. Es zeigt eine Antwort mit 200 Statuscode und Inhaltscodierung von "gzip". Wenn die nächste Anforderung eine andere akzeptable Codierung (z. B.Accept-Encoding: deflate
) und einenIf-None-Match
Header hat, der mit dem Hash des Bundles übereinstimmt, wird die Anforderung in den Kernel- und Benutzermodus-Caches von IIS als Fehlschlag betrachtet . Dadurch wird die Anforderung von der Kassette verarbeitet, die eine 304 zurückgibt:Sobald jedoch der Kernel- und der Benutzermodus von IIS die Antwort verarbeiten, sehen sie, dass sich die Antwort für die URL geändert hat und der Cache aktualisiert werden sollte. Wenn der IIS-Kernel-Cache
netsh http show cachestate
erneut überprüft wird, wird die zwischengespeicherte 200-Antwort durch eine 304-Antwort ersetzt. Alle nachfolgenden Anforderungen an das Bundle, unabhängig vonAccept-Encoding
undIf-None-Match
geben eine 304-Antwort zurück. Wir haben die verheerenden Auswirkungen dieses Fehlers gesehen, bei dem allen Benutzern aufgrund einer zufälligen Anfrage mit einem unerwartetenAccept-Encoding
und ein 304 für unser Kernskript zugestellt wurdeIf-None-Match
.Das Problem scheint zu sein, dass der Cache des IIS-Kernels und des Benutzermodus je nach
Accept-Encoding
Header nicht variieren kann . Als Beweis dafürCache
scheinen bei Verwendung der API mit der folgenden Problemumgehung die IIS-Kernel- und Benutzermodus-Caches immer übersprungen zu werden (nur der ASP.NET-Ausgabecache wird verwendet). Dies kann bestätigt werden, indem überprüft wird, obnetsh http show cachestate
die folgende Problemumgehung leer ist. ASP.NET kommuniziert direkt mit dem IIS-Worker, um den Cache des IIS-Kernels und des Benutzermodus pro Anforderung selektiv zu aktivieren oder zu deaktivieren.Wir konnten diesen Fehler auf neueren Versionen von IIS (z. B. IIS Express 10) nicht reproduzieren. Fehler Nr. 1 war jedoch immer noch reproduzierbar.
Unsere ursprüngliche Lösung für diesen Fehler bestand darin, das Zwischenspeichern des IIS-Kernels / Benutzermodus nur für Kassettenanforderungen zu deaktivieren, wie andere erwähnt haben. Auf diese Weise haben wir Fehler Nr. 1 beim Bereitstellen einer zusätzlichen Caching-Ebene vor unseren Webservern entdeckt. Der Grund, warum der Abfragezeichenfolgen-Hack funktioniert hat, ist, dass der
OutputCacheModule
einen Cache-Fehler aufzeichnet, wenn dieCache
API nicht verwendet wurde, um basierend auf dem zu variieren,QueryString
und wenn die Anforderung eine hatQueryString
.Problemumgehung
Wir hatten sowieso vor, uns von der Kassette zu entfernen. Anstatt unsere eigene Kassettengabel beizubehalten (oder zu versuchen, eine PR zusammenzuführen), haben wir uns für die Verwendung eines HTTP-Moduls entschieden, um dieses Problem zu umgehen.
Ich hoffe das hilft jemandem 😄!
quelle