Mam dziwny problem z IIS 7.
Czasami wydaje się, że zwraca 304 zamiast 200.
Oto przykładowe żądanie przechwycone przez Fiddler:
(Zauważ, że żądany plik nie znajduje się jeszcze w pamięci podręcznej przeglądarki).
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: ...
Zauważ, że w żądaniu nie ma żadnych elementów If-Modified-Since lub If-None-Match.
Ale nadal odpowiedź brzmi:
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
Czy ktoś ma pojęcie, co może być tutaj nie tak?
Używam IIS 7 na Windows Web Server 2008 R2.
EDYTOWAĆ:
Znalazłem obejście, włączyłem buforowanie, a następnie wyłączyłem je na poziomie rozszerzenia.
<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
źródło
źródło
Odpowiedzi:
Według sekcji 14,9 z HTTP1.1 Spec The
no-cache
dyrektywa dla nagłówka Cache-Control jest imposable tylko przez serwer pochodzenia, co oznacza IIS ignoruje nagłówka w swoim wniosku.Sekcja 14.9.1 definiuje
public
,private
ino-cache
jako dyrektyw ograniczających co jest buforowalny, które mogą być nakładane jedynie przez serwer.Jeśli nie chcesz buforować pliku .js, musisz ustawić
no-cache
dyrektywę w aplikacji (tj. Kod ASP.NET) lub zmienićCache-Control
nagłówek w żądaniu, aby użyćno-store
dyrektywy zamiastno-cache
.EDYCJA:
Na podstawie twojego komentarza - tak, zakładam, że nie chcesz buforować pliku. Zatem 304 może pochodzić z powodu umieszczenia pliku w jednej z wewnętrznych pamięci podręcznych IIS. Spójrz na te:
źródło
Od jakiegoś czasu mam ten sam problem i wyłączam buforowanie ... Jednak w pewnym momencie zainstalowałem moduł kompresji dla IIS7, który domyślnie włączył kompresję plików statycznych na moich istniejących stronach. Wyłączyłem całą kompresję dla dotkniętych stron, a teraz wydaje się, że działają dobrze w dotyku drewna .
źródło
Ten błąd również występował, ale korzystaliśmy z biblioteki zarządzania zasobami (kasety). Po dogłębnym zbadaniu tego problemu stwierdziliśmy, że główną przyczyną tego problemu jest kombinacja ASP.NET, IIS i kasety. Nie jestem pewien, czy to jest twój problem (używanie
Headers
interfejsu API zamiastCache
interfejsu API), ale wzorzec wydaje się być taki sam.Błąd nr 1
Cassette ustawia
Vary: Accept-Encoding
nagłówek jako część swojej odpowiedzi na pakiet, ponieważ może kodować zawartość za pomocą gzip / deflate:Jednak wyjściowa pamięć podręczna ASP.NET zawsze zwróci odpowiedź, która była najpierw buforowana. Na przykład, jeśli pierwsze żądanie ma,
Accept-Encoding: gzip
a kaseta zwraca zawartość spakowaną gzip, wyjściowa pamięć podręczna ASP.NET buforuje adres URL jakoContent-Encoding: gzip
. Następne żądanie do tego samego adresu URL, ale z innym dopuszczalnym kodowaniem (np.Accept-Encoding: deflate
), Zwróci buforowaną odpowiedź za pomocąContent-Encoding: gzip
.Ten błąd jest spowodowany przez ustawienie kasety przy użyciu
HttpResponseBase.Cache
interfejsu API do ustawienia wyjściowej pamięci podręcznej (np.Cache-Control: public
), Ale użycieHttpResponseBase.Headers
interfejsu API do ustawieniaVary: Accept-Encoding
nagłówka. Problemem jest to, że ASP.NETOutputCacheModule
jest nie świadomy nagłówków odpowiedzi; działa tylko poprzezCache
API. Oznacza to, że oczekuje od programisty użycia niewidocznie ściśle powiązanego interfejsu API, a nie tylko standardowego protokołu HTTP.Błąd nr 2
Podczas korzystania z IIS 7.5 (Windows Server 2008 R2) błąd nr 1 może powodować osobny problem z jądrem IIS i pamięciami podręcznymi użytkowników. Na przykład po udanym buforowaniu pakietu
Content-Encoding: gzip
można go zobaczyć w pamięci podręcznej jądra IIS za pomocąnetsh http show cachestate
. Pokazuje odpowiedź z kodem stanu 200 i kodowaniem zawartości „gzip”. Jeśli kolejna prośba ma inną dopuszczalną kodowania (npAccept-Encoding: deflate
) i jestIf-None-Match
nagłówek, który pasuje do mieszania wiązki, tym prośba do jądra i trybu użytkownika skrytek IIS będą uważane za chybienie . W ten sposób powodując, że żądanie jest obsługiwane przez kasetę, która zwraca 304:Jednak gdy jądro i tryby użytkownika IIS przetworzą odpowiedź, zobaczą, że odpowiedź na adres URL uległa zmianie i pamięć podręczna powinna zostać zaktualizowana. Jeśli pamięć podręczna jądra IIS zostanie
netsh http show cachestate
ponownie zaznaczona , odpowiedź w pamięci podręcznej 200 zostanie zastąpiona odpowiedzią 304. Wszystkie kolejne żądania do pakietu, niezależnie od tegoAccept-Encoding
iIf-None-Match
zwracają odpowiedź 304. Widzieliśmy druzgocące skutki tego błędu, w którym wszyscy użytkownicy otrzymali 304 dla naszego głównego skryptu z powodu losowego żądania, które miało nieoczekiwaneAccept-Encoding
iIf-None-Match
.Problem polega na tym, że jądra usług IIS i pamięci podręczne trybu użytkownika nie mogą się różnić w zależności od
Accept-Encoding
nagłówka. Jako dowód na to, używającCache
interfejsu API z poniższym obejściem, wydaje się, że pamięci podręczne jądra IIS i trybu użytkownika są zawsze pomijane (używana jest tylko wyjściowa pamięć podręczna ASP.NET). Można to potwierdzić, sprawdzając, czy polenetsh http show cachestate
jest puste, korzystając z poniższego obejścia. Program ASP.NET komunikuje się bezpośrednio z procesorem roboczym IIS w celu selektywnego włączania lub wyłączania pamięci podręcznej jądra IIS i trybu użytkownika na żądanie.Nie byliśmy w stanie odtworzyć tego błędu w nowszych wersjach IIS (np. IIS Express 10). Jednak błąd nr 1 był nadal powtarzalny.
Naszym oryginalnym rozwiązaniem tego błędu było wyłączenie buforowania trybu jądra / trybu użytkownika IIS tylko dla żądań kasety, jak wspomniano inni. W ten sposób odkryliśmy błąd nr 1 podczas wdrażania dodatkowej warstwy buforowania przed naszymi serwerami WWW. Powodem, że siekać ciąg kwerendy pracował dlatego, że
OutputCacheModule
nagra miss cache jeśliCache
API nie został wykorzystany do zależą odQueryString
a jeżeli wniosek maQueryString
.Obejście
W każdym razie planowaliśmy odejść od Cassette, więc zamiast utrzymywać własne rozwidlenie kasety (lub próbować scalić PR), zdecydowaliśmy się użyć modułu HTTP do obejścia tego problemu.
Mam nadzieję, że to komuś pomoże 😄!
źródło