代码之家  ›  专栏  ›  技术社区  ›  Chaddeus

浏览器缓存是否可以通过代码清除?

  •  0
  • Chaddeus  · 技术社区  · 14 年前

    我的网站上有一个菜单,根据用户是否登录而改变。使用浏览器缓存时,菜单在任何一种状态下都会“卡住”,用户会感到困惑。

    他们将登录,但菜单不会更新,因为它仍然缓存在未经验证的状态。。。反之亦然。

    更新

    下面是如何在我的asp.netmvc 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(Duration=60)]。(注意,上面的代码是从 Kazi Manzur Rashid's Blog

    2 回复  |  直到 14 年前
        1
  •  2
  •   Per Bjurström    14 年前

    我一直在玩一个动作过滤器来模拟使用条件请求和电子标签的行为,它是纯客户端缓存,所以这里不涉及输出缓存。您仍然会收到对服务器的请求,但不会调用该操作,如果本地缓存仍然是新的,客户端将使用该缓存。

    /// <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();
        }
    }
    
        2
  •  1
  •   tvanfosson    14 年前

    article 关于这个话题。