IIS 7.で奇妙な問題があります。
時々、200ではなく304を返すようです。
Fiddlerでキャプチャされたリクエストの例を次に示します。
(リクエストされたファイルはまだブラウザのキャッシュにありません。)
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: ...
リクエストにIf-Modified-SinceまたはIf-None-Matchがないことに注意してください。
しかし、それでも応答は次のとおりです。
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
誰かがここで間違っている可能性のある手がかりを持っていますか?
Windows Web Server 2008 R2でIIS 7を実行しています。
編集:
回避策を見つけました。キャッシュを有効にしてから、拡張レベルで無効にするとうまくいきました。
<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>
HTTP1.1仕様のセクション14.9 によると、Cache-Controlヘッダーのno-cache
ディレクティブは、オリジンサーバー、つまりIISはリクエストのヘッダーを無視しています。
キャッシュ制御ディレクティブは、次の一般的なカテゴリに分類できます。
- Restrictions on what are cacheable; these may only be imposed
オリジンサーバーによって。
セクション14.9.1は、public
、private
、およびno-cache
を、キャッシュ可能なものを制限するディレクティブとして定義します。これは、サーバーによってのみ課されることができます。
.jsファイルをキャッシュしたくない場合は、アプリでno-cache
ディレクティブを設定する(つまり、ASP.NETコード)か、使用するリクエストのCache-Control
ヘッダーを変更する必要があります。 no-store
ではなくno-cache
ディレクティブ。
編集:
あなたのコメントに基づいて-はい、ファイルをキャッシュしたくないと思いました。 304は、ファイルがIISの内部キャッシュの1つにあるために発生する可能性があります。これらを見てください:
このバグも発生していましたが、アセット管理ライブラリ(カセット)を使用していました。この問題を詳細に調査した結果、この問題の根本的な原因はASP.NET、IIS、およびカセットの組み合わせにあることがわかりました。これがyourの問題かどうかはわかりません(Headers
APIではなくCache
APIを使用)。パターンは同じようです。
カセットは、gzip/deflateでコンテンツをエンコードできるため、Vary: Accept-Encoding
ヘッダーをバンドルへの応答の一部として設定します。
ただし、ASP.NET出力キャッシュは常に最初にキャッシュされた応答を常に返します。たとえば、最初のリクエストにAccept-Encoding: gzip
があり、カセットがgzip圧縮されたコンテンツを返す場合、ASP.NET出力キャッシュはURLをContent-Encoding: gzip
としてキャッシュします。同じURLへの次のリクエストで、受け入れ可能なエンコーディングが異なる(例:Accept-Encoding: deflate
)と、Content-Encoding: gzip
でキャッシュされた応答が返されます。
このバグは、カセットがHttpResponseBase.Cache
APIを使用して出力キャッシュの設定(Cache-Control: public
など)を設定し、HttpResponseBase.Headers
APIを使用してVary: Accept-Encoding
ヘッダーを設定したことが原因です。問題は、ASP.NETのOutputCacheModule
がnot応答ヘッダーを認識しないことです。 Cache
APIを介してのみ機能します。つまり、開発者が標準のHTTPだけでなく、目に見えない密結合APIを使用することを期待しています。
IIS 7.5(Windows Server 2008 R2))を使用する場合、バグ#1はIISカーネルおよびユーザーキャッシュで別の問題を引き起こす可能性があります。たとえば、バンドルはContent-Encoding: gzip
で正常にキャッシュされ、IISカーネルキャッシュでnetsh http show cachestate
で確認できます。200のステータスコードとコンテンツエンコーディング " gzip "。次のリクエストの受け入れ可能なエンコードが異なる場合(例:Accept-Encoding: deflate
)およびバンドルのと一致するIf-None-Match
ヘッダーハッシュの場合、IISのカーネルおよびユーザーモードキャッシュへの要求はmissと見なされ、304を返すカセットによって要求が処理されます。
ただし、IISのカーネルモードとユーザーモードが応答を処理すると、URLの応答が変更されたことがわかり、キャッシュを更新する必要があります。 IISカーネルキャッシュがnetsh http show cachestate
で再度チェックされると、キャッシュされた200応答は304応答で置き換えられます。Accept-Encoding
に関係なく、バンドルへの後続のすべての要求はIf-None-Match
は304応答を返します。予期しないAccept-Encoding
とIf-None-Match
のあるランダムリクエストが原因で、すべてのユーザーにコアスクリプトの304が提供されたこのバグの壊滅的な影響がわかりました。 。
問題は、IISカーネルおよびユーザーモードのキャッシュがAccept-Encoding
ヘッダーに基づいて変更できないことです。これの証拠として、Cache
APIを回避策とともに使用することにより、以下では、IISカーネルおよびユーザーモードキャッシュは常にスキップされるようです(ASP.NET出力キャッシュのみが使用されます)。これは、netsh http show cachestate
がASP.NETはIISワーカーと直接通信して、要求ごとにIISカーネルおよびユーザーモードキャッシュを選択的に有効または無効にします。
IIS(例:IIS Express 10))の新しいバージョンでこのバグを再現することはできませんでしたが、バグ#1は再現可能でした。
このバグに対する最初の修正は、IISカーネル/ユーザーモードキャッシングを他の言及したようなカセットリクエストに対してのみ無効にすることでした。これにより、前に追加のキャッシングレイヤーをデプロイするときにバグ#1を発見しました。クエリ文字列ハックが機能したのは、OutputCacheModule
APIがCache
に基づいて変化するために使用されていない場合、 QueryString
はキャッシュミスを記録するためですリクエストにQueryString
がある場合。
私たちはとにかくカセットから離れることを計画していたので、カセットのフォークを維持する(またはPRをマージしようとする)のではなく、この問題を回避するためにHTTPモジュールを使用することを選びました。
public class FixCassetteContentEncodingOutputCacheBugModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.PostRequestHandlerExecute += Context_PostRequestHandlerExecute;
}
private void Context_PostRequestHandlerExecute(object sender, EventArgs e)
{
var httpContext = HttpContext.Current;
if (httpContext == null)
{
return;
}
var request = httpContext.Request;
var response = httpContext.Response;
if (request.HttpMethod != "GET")
{
return;
}
var path = request.Path;
if (!path.StartsWith("/cassette.axd", StringComparison.InvariantCultureIgnoreCase))
{
return;
}
if (response.Headers["Vary"] == "Accept-Encoding")
{
httpContext.Response.Cache.VaryByHeaders.SetHeaders(new[] { "Accept-Encoding" });
}
}
public void Dispose()
{
}
}
これが誰かに役立つことを願っています????!
しばらく同じ問題が発生し、すべてのキャッシュがオフになっています...しかし、IIS7の圧縮モジュールをインストールしたところ、デフォルトで既存のサイトで静的ファイルの圧縮が有効になりました。影響を受けたサイトのすべての圧縮をオフにしたところ、現在は正常に動作しているようですtouch wood。