編集済み
クライアントに画像をキャッシュしたいのですが、mvc 3でそれを行うにはさまざまな方法があることを知っています(間違っている場合は修正してください)
1)httpヘッダーOutputCacheAttribute
の助けを借りて動作するものを使用できます。ただし、時間が経過しない限り(画像が変更された場合でも)Expires
戻ります。304 Not Modified
2)古い画像が表示されないようにするにはLast-Modified
httpヘッダー(を使用OutputCacheAttribute
)を使用できます。この場合、ブラウザはIf-Modified-Since
httpヘッダーを使用してサーバーにリクエストを送信します。サーバー上でオブジェクトがまだ有効かどうかを確認し、有効かどうかを確認しますLast-Modified
。httpヘッダーを返すだけです(ブラウザはローカルキャッシュから画像を取得します)。オブジェクトが変更された場合200 OK
ステータスとともに返します。
そのため、ブラウザは、自身のキャッシュから画像を取得する前に、毎回サーバーにリクエストを送信する必要があります。これが例です-
3)別の方法があります(私の場合は正しい方法で言われたので、画像がほとんど変更されないためです...とにかく、これを正確に実装する必要があります):変更された日付を画像のURLに追加し、次のようにキャッシュを設定しますExpires
永遠に(1年以上)。画像が変更された場合新しいバージョンの新しいURLを送信する必要があります。
コードは次のとおりです。
public class LastModifiedCacheAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Result is FilePathResult)
{
var result = (FilePathResult)filterContext.Result;
var lastModify = File.GetLastWriteTime(result.FileName);
if (!HasModification(filterContext.RequestContext, lastModify))
filterContext.Result = NotModified(filterContext.RequestContext, lastModify);
SetLastModifiedDate(filterContext.RequestContext, lastModify);
}
base.OnActionExecuted(filterContext);
}
private static void SetLastModifiedDate(RequestContext requestContext, DateTime modificationDate)
{
requestContext.HttpContext.Response.Cache.SetLastModified(modificationDate);
}
private static bool HasModification(RequestContext context, DateTime modificationDate)
{
var headerValue = context.HttpContext.Request.Headers["If-Modified-Since"];
if (headerValue == null)
return true;
var modifiedSince = DateTime.Parse(headerValue).ToLocalTime();
return modifiedSince < modificationDate;
}
private static ActionResult NotModified(RequestContext response, DateTime lastModificationDate)
{
response.HttpContext.Response.Cache.SetLastModified(lastModificationDate);
return new HttpStatusCodeResult(304, "Page has not been modified");
}
}
そしてLastModifiedCacheAttribute
、Global.asaxに登録し、次のOutputCacheAttributeをアクションメソッドに適用しました。
[HttpGet, OutputCache(Duration = 3600, Location = OutputCacheLocation.Client, VaryByParam = "productId")]
public FilePathResult GetImage(int productId)
{ // some code }
上記のコードを使用すると、ブラウザはサーバーにリクエストを送信せず、代わりに、期間が終了しない限り、キャッシュから画像を取得するように見えます。(画像を変更すると、ブラウザに新しいバージョンが表示されません)
質問:
1) 3番目のアプローチを実装して、画像が変更されない限り、ブラウザがクライアントキャッシュから画像を取得する(そして、画像が必要になるたびにサーバーに応答を送信しない)ようにするにはどうすればよいですか?
編集済み:実際のコードを高く評価します。
2)上記のコードでは、最初の画像リクエストの時刻がLast-Modifiedに書き込まれます(理由はわかりません)。ファイルの変更日をLast-Modifiedに書き込む方法は?
編集:この質問は2番目のアプローチに関連しています。また、クライアントのみにキャッシュしてLast-Modified
実装を使用すると304 Not Modified
、を押した場合にのみステータスが取得されますF5
。同じURLを再入力すると、が取得されます200 OK
。使用せずにクライアントにキャッシュすると、何があっLast-Modified
ても常に返されます。200 OK
これはどのように説明できますか?