Можно ли очистить кеш браузера через код? - PullRequest
0 голосов
/ 18 сентября 2010

У меня есть меню на моем сайте, которое меняется в зависимости от того, вошел ли пользователь в систему или нет. При кэшировании в браузере меню «застревает» в любом состоянии и вводит пользователей в заблуждение.

Они войдут в систему, но меню не обновится, потому что оно все еще кэшируется в состоянии без проверки подлинности ... и наоборот.

Как это обычно обрабатывается? Можем ли мы обновить кэш браузера пользователя из нашего кода? Или я просто не разрешаю кеширование в браузере? (лучше использовать, очень хороший удар по скорости).

Обновление

Вот как настроить кэширование на стороне клиента в моем приложении 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 (Duration = 60)] к моим действиям. (обратите внимание, я получил код выше из Блог Кази Манзура Рашида

Ответы [ 2 ]

2 голосов
/ 19 сентября 2010

Я немного поигрался с фильтром действий для имитации этого поведения, используя условные запросы и электронные теги, это чисто кэширование на стороне клиента, поэтому здесь не используется кэширование вывода.Вы по-прежнему получаете запрос к серверу, но действие не будет вызвано, и клиент будет использовать локальный кэш, если он еще свежий.

/// <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();
    }
}
1 голос
/ 18 сентября 2010

Возможно, вы захотите попробовать кэширование пончиков и кэшировать все, кроме меню. У Скотта Гатри есть хорошая статья на эту тему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...