禁用所有操作的浏览器缓存,但保留捆绑包

在我正在处理的MVC应用程序中,出于安全原因,我们不得不在所有操作上阻止浏览器缓存(防止用户在注销后返回历史记录)。 我们使用此解决方案实现了此目

但是,我们确实希望允许浏览器缓存css和js包。 不幸的是,上面提到的解决方案似乎阻止了所有资源的缓存。 在本地机器上,它甚至包括静态文件,如图像,但在远程服务器上IIS处理这些文件(而不是应用程序本身),这样就不用担心了。 无论如何,是否有一些方法可以调整此解决方案以允许浏览器缓存捆绑包?

我知道我可以使用像这样的filter并将其添加到所有操作(甚至更好,所有控制器)或添加一个新的基本控制器,默认情况下具有此filter,并将我的所有控制器设置为inheritance它,但有没有更好的选择(不涉及更改项目中的无数文件)?

PS写完这个问题让我想到了一些我必须尝试的解决方案。 这件事发生在我之前。 我的意思是,在这里写一个问题时找到正确的答案,但我最后没有发布这些问题。


在写这个问题时我觉得的解决方案非常简单。 只需在Application_BeginRequest写一个简单的if条件,以确定资源是否应该是可缓存的,基于请求url …我还没有测试它,但听起来它可能只是做这项工作。

我们使用全局filter完成了您的原始要求。 在Global.asax.cs中:

 GlobalFilters.Filters.Add(new NoCacheAttribute()); 

NoCacheAttribute:

 ///  /// An attribute that can be attached to an individual controller or used globally to prevent the browser from caching the response. /// This has nothing to do with server side caching, it simply alters the response headers with instructions for the browser. ///  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] public class NoCacheAttribute : ActionFilterAttribute { public override void OnResultExecuting(ResultExecutingContext filterContext) { if (!filterContext.IsChildAction && !(filterContext.Result is FileResult)) { filterContext.HttpContext.Response.Cache.SetExpires(DateTime.MinValue); filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false); filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache); filterContext.HttpContext.Response.Cache.SetNoStore(); base.OnResultExecuting(filterContext); } } } 

这会影响我们所有的控制器操作,但只留下静态内容和其他所有操作。 Bundling框架处理它自己的缓存:它基本上告诉浏览器永远缓存,但在URL中包含一个缓存破坏令牌,如果修改了任何捆绑文件,则该哈希值会发生变化。 此机制不受此filter的影响。 (我不知道是不是因为没有应用全局filter,或者因为它产生了FileResult – 我怀疑是前者。)

这是我在原始问题中提到的解决方案。 它非常简单(有点脏),但似乎有效。

 protected void Application_BeginRequest() { // Here we check if the request was for bundle or not and depending on that // apply the cache block. if (!Request.Url.PathAndQuery.StartsWith("/bundles/")) { Response.Cache.SetAllowResponseInBrowserHistory(false); Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.Cache.SetNoStore(); Response.Cache.SetExpires(DateTime.Now); Response.Cache.SetValidUntilExpires(true); } } 

在我的本地环境中,我还将/Content/文件夹添加到条件中,但它在远程服务器上是多余的,因为IIS将处理这些(除非您明确告诉它不要)。