25

カスタム IHttpHandler を作成しているときに、HttpCachePolicy オブジェクトに関して予期しない動作に遭遇しました。

私のハンドラーは、エンティティ タグを計算して設定します (現在の応答オブジェクトに関連付けられた HttpCachePolicy で SetETag メソッドを使用します)。SetCacheability メソッドを使用してキャッシュ コントロールを public に設定すると、すべてが魅力的に機能し、サーバーは e-tag ヘッダーに沿って送信します。プライベートに設定すると、e-tag ヘッダーは抑制されます。

十分に調べていないだけかもしれませんが、HTTP/1.1 仕様には、この動作を正当化するものは何もありません。プロキシがデータを保存することを禁止しながら、ブラウザに E-Tag を送信したくないのはなぜですか?

using System;
using System.Web;

public class Handler : IHttpHandler {
    public void ProcessRequest (HttpContext ctx) {
        ctx.Response.Cache.SetCacheability(HttpCacheability.Private);
        ctx.Response.Cache.SetETag("\"static\"");
        ctx.Response.ContentType = "text/plain";
        ctx.Response.Write("Hello World");
    }

    public bool IsReusable { get { return true; } }
}

戻ります

キャッシュ制御: プライベート
コンテンツ タイプ: テキスト/プレーン。文字セット=utf-8
コンテンツの長さ: 11

しかし、それを public に変更すると、元に戻ります

キャッシュ制御: 公開
コンテンツ タイプ: テキスト/プレーン。文字セット=utf-8
コンテンツの長さ: 11
Etag: "静的"

これまでのところ、ASP.NET 開発サーバーと IIS6 でこれを実行しましたが、結果は同じでした。また、を使用して ETag を明示的に設定することはできません

Response.AppendHeader("ETag", "static")

更新: IIS7 で実行している場合、ETag ヘッダーを手動で追加することができます。これは、ASP.NET と IIS7 パイプラインの間の緊密な統合が原因であると思われます。

明確化: 長い質問ですが、中心的な質問は次のとおりです。ASP.NET はなぜこのようなことを行うのでしょうか。

更新:基本的に正しいので、トニーの答えを受け入れるつもりです(トニーに行きましょう!)。HttpCacheability.Private を完全にエミュレートしたい場合は、キャッシュ可能性を ServerAndPrivate に設定できますが、呼び出しキャッシュもあります。SetOmitVaryStar (true) そうしないと、キャッシュによってVary: *ヘッダーが出力に追加されますが、それは望ましくありません。編集権限を取得したら、それを回答に編集します(または、このトニーが表示された場合は、回答を編集してその呼び出しを含めることができますか?)

4

3 に答える 3

17

I think you need to use HttpCacheability.ServerAndPrivate

That should give you cache-control: private in the headers and let you set an ETag.

The documentation on that needs to be a bit better.

Edit: Markus found that you also have call cache.SetOmitVaryStar(true) otherwise the cache will add the Vary: * header to the output and you don't want that.

于 2008-08-29T05:25:27.503 に答える
3

残念ながらSystem.Web.HttpCachePolicy.UpdateCachedHeaders()、.NET Reflector を見ると、ETag 処理を実行する前に Cacheability が Private でないことを具体的にチェックする if ステートメントがあることがわかります。いずれにせよ、私は常にそれがLast-Modified/If-Modified-Since私たちのデータにうまく機能し、とにかく Fiddler で監視するのが少し簡単であることを発見しました.

于 2008-08-28T22:27:44.247 に答える
1

私のように、Cacheability.ServerAndPrivateを使用するというここで説明した回避策に不満があり、代わりにプライベートを使用したい場合は、おそらくユーザー向けにページを個別にカスタマイズしていて、サーバーにキャッシュする意味がないためです。 .NET 3.5では、Response.Headers.Addを介してETagを設定でき、これは正常に機能します。

注意:これを行う場合は、クライアントヘッダーとHTTP304応答処理の比較を自分で実装する必要があります。通常の状況で.NETがこれを処理するかどうかはわかりません。

于 2012-03-30T00:12:35.920 に答える