ASP.NET应用Content-Encoding头重复添加gzip导致内容编码错误排查
问题背景
我目前在维护一个传统ASP.NET Web应用,其中有一个.aspx页面承载了Angular 11应用,90%的情况下加载正常,但偶尔会返回状态码为200 OK的异常响应。此时Firefox会弹出“content encoding error”提示,Chrome和Edge则显示空白页,控制台也会输出相同的内容编码错误日志。
使用Wireshark排查后发现,出现内容编码错误时,响应头的Content-Encoding字段被追加了三个逗号分隔的“gzip”值,示例如下:
HTTP/1.1 200 OK Cache-Control: no-cache, no-store, must-revalidate Content-Type: text/html; charset=utf-8 Content-Encoding: gzip, gzip, gzip ...
而该.aspx页面的正常响应如下:
HTTP/1.1 200 OK Cache-Control: no-cache, no-store, must-revalidate Content-Type: text/html; charset=utf-8 Content-Encoding: gzip ..
我可以通过aspx的[web method]调用复现该问题:
var ctx = HttpContext.Current var unused = ctx.Response.Filter // 必须先访问该属性才能进行赋值 ctx.Response.Filter = new GZipStream(ctx.Response.OutputStream, CompressionLevel.Optimal) ctx.Response.AppendHeader("Content-Encoding", "gzip") ctx.Response.AppendHeader("Content-Encoding", "gzip") // <--此处gzip被重复添加
棘手的是,多个gzip值是出现在aspx页面本身的响应中,我已经检索了整个代码库和所有web.config文件,试图定位压缩逻辑的位置但没有结果,因此怀疑是第三方组件导致的该问题。
我们的项目使用了DevExtreme,我已经核查了配置中的如下设置:
<add key="DXEnableCallbackCompression" value="true" /> <add key="DXEnableResourceCompression" value="true" /> <add key="DXEnableResourceMerging" value="true" /> <add key="DXEnableHtmlCompression" value="true" />
我目前仍未能在代码中定位到问题根源,请问有没有借助Fiddler、Wireshark或其他工具,定位该响应头偶发出现三个gzip值的技巧?
编辑补充
如下是90%情况下返回正常编码响应对应的GET请求头:
GET http://xxx/xxx.aspx?xxx=4 HTTP/1.1 Host: xxx.com Connection: keep-alive Pragma: no-cache Cache-Control: no-cache Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.73 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://xxx/Home.aspx Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.9 Cookie: ASP.NET_SessionId=x; .ASPXAUTH=x;
问题触发时机
我已经可以稳定复现该问题:关闭所有浏览器会话并回收应用程序池后,首次请求就会触发该问题,后续请求则不会出现。
同时定位到问题诱因是HTML页面中嵌入的谷歌脚本,移除该脚本后,无论是否回收应用池,首次请求都能正常加载。
问题代码
<script type="text/javascript" src="//maps.googleapis.com/maps/api/js?key= <%=GoogleMapAPIKey%>&channel=<%=GoogleMappingChannel%>"></script>
我可以确定不是js文件本身的问题,标签中的密钥是通过服务端处理程序嵌入的,这两个处理程序会调用API获取密钥,且这些API调用是gzip压缩的。但我仍然不清楚为什么页面标记中存在该js引入语句时,aspx的响应头会出现三个gzip值。基于这些新发现,我可能会整理内容后提出新的问题。
内容的提问来源于stack exchange,提问作者Ross Bush

