ASP.NET MVC5中Gzip压缩失效及Chrome不返回304缓存问题求助
问题一:Chrome按F5刷新不发送If-Modified-Since请求头的原因与解决办法
原因
这其实是Chrome自身的缓存策略差异导致的:当资源设置了**长期Expires(比如1年)**且处于缓存有效期内时,Chrome在F5刷新时会直接从本地缓存加载资源(返回200 OK (from cache)),不会向服务器发送If-Modified-Since验证请求。而IE11、Edge、Firefox在F5刷新时,即使资源未过期,也会主动发起验证请求确认资源是否更新。
解决办法
如果希望Chrome在F5刷新时也触发服务器验证,可以调整缓存头策略,结合must-revalidate指令:
Response.Cache.SetCacheability(HttpCacheability.Public); // 用max-age替代Expires,同时添加must-revalidate强制验证 Response.Cache.SetMaxAge(TimeSpan.FromYears(1)); Response.Cache.AppendCacheExtension("must-revalidate"); Response.Cache.SetLastModified(System.IO.File.GetLastWriteTime(serverPath).ToUniversalTime()); Response.AppendHeader("Vary", "Accept-Encoding");
must-revalidate会强制浏览器在缓存有效期内,每次刷新都向服务器验证资源状态,这样Chrome就会发送If-Modified-Since请求了。另外,也可以搭配ETag使用(添加Response.Cache.SetETag(生成的ETag值)),ETag是资源的唯一标识,服务器可以通过它更精准地判断资源是否更新。
问题二:Gzip压缩过滤器在IIS10 + .NET4.7环境不生效的排查方向
你的压缩过滤器在旧环境正常,但IIS10 + .NET4.7下失效,结合你提供的响应头(无Content-Encoding: gzip),可以从以下几个方向排查:
禁用IIS自带压缩,避免冲突
IIS10默认可能开启了动态/静态压缩,即使你不想用IIS压缩,它也可能提前处理响应流,覆盖你的过滤器设置。可以在web.config中添加配置禁用:<system.webServer> <urlCompression dynamicCompressionEnabled="false" staticCompressionEnabled="false" /> </system.webServer>调整过滤器的执行时机
你当前在OnActionExecuting(Action执行前)处理压缩,但此时响应流还未生成,后续Action执行可能会覆盖Response.Filter。建议把压缩逻辑移到OnResultExecuting(结果执行前),这个时机响应流已经准备就绪:public override void OnResultExecuting(ResultExecutingContext filterContext) { GZipEncodePage(); base.OnResultExecuting(filterContext); }确保响应缓冲开启
如果Response.BufferOutput为false,流式输出会导致压缩过滤器无法生效,在GZipEncodePage方法开头添加:HttpResponse Response = HttpContext.Current.Response; Response.BufferOutput = true; // 开启缓冲,确保压缩能处理完整响应流检查GZipStream的创建参数
.NET4.7中GZipStream的默认leaveOpen参数为false,可能导致响应流提前关闭。修改创建逻辑:Response.Filter = new System.IO.Compression.GZipStream(Response.Filter, System.IO.Compression.CompressionMode.Compress, leaveOpen: true);排查其他过滤器或模块干扰
检查是否有其他ActionFilter、HttpModule修改了Response.Filter或Content-Encoding头,比如某些日志模块、安全模块可能会篡改响应流。测试最小化场景
写一个简单的测试Action(比如返回一段纯文本),只应用你的压缩过滤器,用Chrome开发者工具或Fiddler查看响应头,确认是否出现Content-Encoding: gzip,排除业务代码的干扰。
补充:你提供的响应头信息:
HTTP/1.1 200 OK Cache-Control: public Content-Type: text/javascript Expires: Sat, 18 May 2019 08:58:48 GMT Last-Modified: Thu, 10 May 2018 13:26:02 GMT Vary: Content-Encoding Server: Microsoft-IIS/10.0 X-AspNetMvc-Version: 5.2 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Fri, 18 May 2018 08:58:48 GMT Transfer-Encoding: chunked
内容的提问来源于stack exchange,提问作者lkurylo

