2010-09-18 123 views
0

我的網站上有一個菜單,根據用戶是否登錄進行更改。通過瀏覽器緩存,菜單在任何一種狀態下都會「卡住」,並且會讓用戶感到困惑。是否可以通過代碼清理瀏覽器緩存?

他們會登錄,但菜單不會更新,因爲它仍然處於未認證狀態,反之亦然。

這是如何處理的?我們可以從我們的代碼刷新用戶的瀏覽器緩存嗎?或者我只是不允許瀏覽器緩存? (寧願使用它,速度非常好)。

更新

下面是如何設置的客戶端,瀏覽器緩存在我的asp.net MVC 2應用程序:

public class CacheFilterAttribute : ActionFilterAttribute { 
    /// <summary> 
    /// Gets or sets the cache duration in seconds. The default is 10 seconds. 
    /// </summary> 
    /// <value>The cache duration in seconds.</value> 
    public int Duration { get; set; } 

    public CacheFilterAttribute() { Duration = 10; } 

    public override void OnActionExecuted(ActionExecutedContext filterContext) { 
     if (Duration <= 0) return; 

     var cache = filterContext.HttpContext.Response.Cache; 
     var cacheDuration = TimeSpan.FromSeconds(Duration); 

     cache.SetCacheability(HttpCacheability.Public); 
     cache.SetExpires(DateTime.Now.Add(cacheDuration)); 
     cache.SetMaxAge(cacheDuration); 
     cache.AppendCacheExtension("must-revalidate, proxy-revalidate"); 
    } 
} 

,然後應用[CachFilter(持續時間= 60)],以我的行動。 (注意,我從Kazi Manzur Rashid's Blog得到了上面的代碼

回答

2

我一直在玩周圍bit使用動作過濾器來模擬使用條件請求和電子標籤的行爲,它是純粹的客戶端緩存,所以在這裏沒有輸出緩存,你仍然可以獲得對服務器的請求,但不會調用動作,客戶端將使用本地緩存如果它仍然是新鮮的。

/// <summary> 
/// Handles client side caching by automatically refreshing content when switching logged in identity 
/// </summary> 
public class ClientCacheByIdentityAttribute : ActionFilterAttribute 
{ 
    /// <summary> 
    /// Sets the cache duraction in minutes 
    /// </summary> 
    public int Duration { get; set; } 

    /// <summary> 
    /// Check for incoming conditional requests 
    /// </summary> 
    /// <param name="filterContext"></param> 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     if (filterContext.IsChildAction || filterContext.HttpContext.Request.RequestType!="GET" || filterContext.Result!=null) 
     { 
      return; 
     } 

     string modifiedSinceString = filterContext.HttpContext.Request.Headers["If-Modified-Since"]; 
     string noneMatchString = filterContext.HttpContext.Request.Headers["If-None-Match"]; 

     if (String.IsNullOrEmpty(modifiedSinceString) || String.IsNullOrEmpty(noneMatchString)) 
     { 
      return; 
     } 

     DateTime modifiedSince; 

     if (!DateTime.TryParse(modifiedSinceString, out modifiedSince)) 
     { 
      return; 
     } 

     if (modifiedSince.AddMinutes(Duration) < DateTime.Now) 
     { 
      return; 
     } 

     string etag = CreateETag(filterContext.HttpContext); 

     if (etag == noneMatchString) 
     { 
      filterContext.HttpContext.Response.StatusCode = 304; 
      filterContext.Result = new EmptyResult(); 
     } 
    } 

    /// <summary> 
    /// Handles setting the caching attributes required for conditional gets 
    /// </summary> 
    /// <param name="filterContext"></param> 
    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     if (filterContext.HttpContext.Request.RequestType == "GET" && filterContext.HttpContext.Response.StatusCode == 200 && !filterContext.IsChildAction && !filterContext.HttpContext.Response.IsRequestBeingRedirected) 
     { 
      filterContext.HttpContext.Response.AddHeader("Last-Modified", DateTime.Now.ToString("r")); 
      filterContext.HttpContext.Response.AddHeader("ETag", CreateETag(filterContext.HttpContext)); 
     } 
    } 

    /// <summary> 
    /// Construct the ETag 
    /// </summary> 
    /// <param name="context"></param> 
    /// <returns></returns> 
    private static string CreateETag(HttpContextBase context) 
    { 
     return "\"" + CalculateMD5Hash(context.Request.Url.PathAndQuery + "$" + context.User.Identity.Name) + "\""; 
    } 

    /// <summary> 
    /// Helper to make an MD5 hash 
    /// </summary> 
    /// <param name="input"></param> 
    /// <returns></returns> 
    private static string CalculateMD5Hash(string input) 
    { 
     MD5 md5 = MD5.Create(); 
     byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input); 
     byte[] hash = md5.ComputeHash(inputBytes); 

     StringBuilder sb = new StringBuilder(); 
     for (int i = 0; i < hash.Length; i++) 
     { 
      sb.Append(hash[i].ToString("X2")); 
     } 
     return sb.ToString(); 
    } 
} 
+0

謝謝,我會盡快覈實這一點。如果它幫助我,我會報告。非常感激。 – Chaddeus 2010-09-19 14:17:01

+0

優雅的解決方案和完美的結果!你救我!謝謝! – 2016-02-25 18:00:47

1

你可能想嘗試甜甜圈洞緩存和緩存以外的所有菜單。斯科特·加斯里對主題一個很好的article

+0

感謝您的鏈接。我知道輸出緩存在asp.n等。我所指的是客戶端瀏覽器緩存。我編輯了我的答案,以顯示如何設置瀏覽器緩存超時。謝謝! – Chaddeus 2010-09-19 02:06:44

相關問題