MVC4脚本包缓存问题

我们有一个MVS应用程序,我们使用Bundle类捆绑javascript代码(不要做缩小)。

捆绑工作正常,但是当我们运行应用程序时,缓存值设置为Cache-Control:no-cache ,同时每次刷新页面时请求总是有200 OK。 这意味着即使没有更改,js也不会缓存在客户端上。

还有一种方法可以validation捆绑的js是动态构建还是从服务器缓存中获取?

谢谢

我看到了与codeplex链接中描述的相同的行为,提到了这个问题:

即如果我按以下顺序访问这些URL,则行为是 –

bundle.css?v=1234 : no-cache bundle.css : public bundle.css?v=1234 : public 

我决定深入研究一下System.Web.Optimization源代码,看看发生了什么。 在Bundle类中,有一个私有方法设置标题,它似乎属于这段代码:

 if (noCache) { cachePolicy.SetCacheability(HttpCacheability.NoCache); } 

noCache变量通过参数设置。 在这种情况下调用方法是设置它:

 // Set to no-cache if the version requested does not match bool noCache = false; var request = context.HttpContext.Request; if (request != null) { string queryVersion = request.QueryString.Get(VersionQueryString); if (queryVersion != null && bundleResponse.GetContentHashCode() != queryVersion) { noCache = true; } } 

简而言之,我们已经切换到使用Azure CDN作为我们的捆绑包,并根据程序集版本将版本查询字符串参数更改为类似?v = 1.0.0.0(类似于此问题 )。 捆绑代码将“1.0.0.0”与捆绑包内容的SHA256哈希代码进行比较,并将结果标记为无缓存的捆绑包。

我通过更新查询字符串以匹配内容哈希来解决这个问题。

不幸的是,GetContentHashCode方法的访问级别标记为内部,因此有必要复制实现 。 我最终创建了一个inheritance自Bundle的类,以便它可以将版本号作为转换应用于CdnPath:

 public class ProxiedCdnBundle : Bundle { private readonly string _cdnHost; public ProxiedCdnBundle(string virtualPath, string cdnHost = "") : base(virtualPath) { _cdnHost = cdnHost; } public override BundleResponse ApplyTransforms(BundleContext context, string bundleContent, IEnumerable bundleFiles) { var response = base.ApplyTransforms(context, bundleContent, bundleFiles); if (context.BundleCollection.UseCdn && !String.IsNullOrWhiteSpace(_cdnHost)) { string path = System.Web.VirtualPathUtility.ToAbsolute(context.BundleVirtualPath); base.CdnPath = string.Format("{0}{1}?v={2}", _cdnHost, path, GetBundleHash(response)); } return response; } private static string GetBundleHash(BundleResponse response) { using (var hashAlgorithm = CreateHashAlgorithm()) { return HttpServerUtility.UrlTokenEncode(hashAlgorithm.ComputeHash(Encoding.Unicode.GetBytes(response.Content))); } } private static SHA256 CreateHashAlgorithm() { if (CryptoConfig.AllowOnlyFipsAlgorithms) { return new SHA256CryptoServiceProvider(); } return new SHA256Managed(); } } 

问题似乎与Microsoft.AspNet.Web.Optimization NuGet包有关。 将版本从1.3.0降级到1.1.0后,一切似乎都运行正常。

链接到codeplex的博客文章,提到了同样的问题

由于上面的答案对我没有帮助(不确定后果),我找到了解决这个问题的方法。

问题是,如此处所述,当您在查询字符串上发送?v并且该值与实际哈希值不匹配时,它将返回no-cache

根本不发送任何内容不是一个选项(缓存可能永远不会过期)。 发送缓存清除参数也不是一种选择。 如果您这样做并且您有多个实例,则可能在部署期间缓存错误的值(如果您没有从负载均衡器中删除旧实例)。

要解决此问题,只需将UseCdn设置为false并在捆绑配置期间更改以下内容:

 Scripts.DefaultTagFormat = string.Format(@"", CdnRoot); 

希望,我帮了。