【问题标题】:How do I add site-wide no-cache headers to an MVC 3 app如何将站点范围的无缓存标头添加到 MVC 3 应用程序
【发布时间】:2011-08-17 04:14:52
【问题描述】:

我构建了一个 MVC3 应用程序,应用程序有很多页面,现在因为安全问题我需要在 http 标头中添加无缓存设置,有没有更简单的方法呢?如果我们可以修改一个地方,那么它将适用于整个应用程序,这将是完美的。

你们能帮帮我吗?

【问题讨论】:

  • 我已经编辑了我的答案以使用 Response.Cache.SetCacheability() 方法而不是手动设置标题。在 Fiddler 中测试并按预期工作。

标签: c# asp.net-mvc asp.net-mvc-3


【解决方案1】:

如何在 Global.asaxApplication_PreSendRequestHeaders 事件中设置 Headers

编辑 你可以使用Response.Cache.SetCacheability而不是直接设置Headers。*

void Application_PreSendRequestHeaders(Object sender, EventArgs e)
{
    Response.Cache.SetCacheability(HttpCacheability.NoCache);
}

在 Fiddler 中测试。


手动设置标题的替代方式。

void Application_PreSendRequestHeaders(Object sender, EventArgs e) {
    Response.Headers.Set("Cache-Control", "no-cache");
}

【讨论】:

  • 没有缓存太多了!如果您这样做,您将不会缓存所有 javascript、css、图标等,并且会在您的带宽和响应能力上做很多事情。
  • @ScottStafford 阅读 OPs 请求“如果我们可以修改一个地方,那么它将适用于整个应用程序,这将是完美的。”显然,可以过滤某些文件,但这不是所要求的。
  • 我知道他说过。我没有 -1 或任何东西,但我想确保他(和任何其他读者)知道这种强硬方法的后果是什么。对“这是一个 aspx 文件”进行测试,它的适用性要广泛得多。
  • @ScottStafford,那个(.aspx 过滤器)在 MVC 中并不真正起作用,但应该进行类似的过滤。
【解决方案2】:

对于那些想要方法/动作或类/控制器范围的人的替代品no-cache

[OutputCache(Location = OutputCacheLocation.None)]
public class HomeController : Controller
{
...
}

如下所述:

OutputCacheLocation Enumeration

无:为请求的页面禁用输出缓存。这个值 对应HttpCacheability.NoCache枚举值。

HttpCacheability Enumeration

NoCache - 设置 Cache-Control: no-cache 标头....

【讨论】:

【解决方案3】:

设置全局过滤器。

public class MvcApplication : System.Web.HttpApplication
{

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new NoCacheGlobalActionFilter());
    }    
}

public class NoCacheGlobalActionFilter : ActionFilterAttribute
{
    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
        cache.SetCacheability(HttpCacheability.NoCache);

        base.OnResultExecuted(filterContext);
    }
}

http://dotnet.dzone.com/articles/output-caching-aspnet-mvc

【讨论】:

    【解决方案4】:

    我会在 IIS 本身(假设您正在使用它)或 web.config 中执行此操作:

    <configuration>
       <system.webServer>
          <staticContent>
             <clientCache cacheControlMode="DisableCache" />
          </staticContent>
       </system.webServer>
    </configuration>
    

    代码越少越好。

    根据 IIS 的版本,设置略有不同。

    请参阅here 了解更多信息。

    【讨论】:

    • 该配置是否仅适用于静态内容(img、js、css 等),还是名称有点误导?从 IIS 网站上看不太清楚。
    • @Troy - 我 认为 这就是一切。很容易测试,只需检查 fiddler/firebug/etc 中的响应标头
    • 从应用程序控制缓存对我来说似乎更合适,因为我预计大多数人都希望缓存静态内容。另外,我不会说您的解决方案需要更少的代码:-)。
    • 它确实需要更少的代码。这只是一个 web.config 更改。换句话说,它不必重新编译和修补,它可以转到根 web.config 并在必要时在站点范围内应用。谢谢,顺便说一句,正是我想要的!
    【解决方案5】:

    我建议这些调用仅限于非 GET 请求,以避免失去 GET 缓存的好处。以下确保即使是像 iOS 6 Safari 这样激进的缓存浏览器也不会缓存任何不是 GET 请求的内容。

    出于多种原因,我使用了一个 Controller 基类,我的所有控制器都从该基类继承,这很好,因为我的 Initialize 覆盖可以有条件地设置我的缓存头。

    public class SmartController : Controller
    {
        ...
        public HttpContextBase Context { get; set; }
    
        protected override void Initialize(System.Web.Routing.RequestContext requestContext)
        {
            Context = requestContext.HttpContext;
    
            if (Context.Request.RequestType != "GET")
            {
                Context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            }
    
            base.Initialize(requestContext);
            ...
        }
    ...
    }
    

    【讨论】:

    • 基于 HTTP 动词设置缓存策略对于各种应用程序来说是不够的。假设您有一个页面,您在其中使用 GET 和查询字符串来加载医院患者数据?您不想缓存该页面。
    • Larry,在这种情况下,您肯定不想像我在这里建议的那样实现基本控制器逻辑。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-04
    • 2017-03-30
    • 1970-01-01
    • 2016-06-28
    • 1970-01-01
    • 2012-05-26
    相关资源
    最近更新 更多