TLDR
我有一个IHttpHandler
执行压缩的。它自己工作得很好。但是后来我添加了IHttpModule
一个对这些(以及所有其他)响应执行完全不相关的任务,现在 IIS 正在重新压缩已经压缩的响应。我怎样才能防止这种情况?
整个故事
我有一个IHttpHandler
为 CSS 和 JS 文件执行组合和压缩(除其他外)的实现。作品中的一切都IHttpHandler
完全符合我的要求。
但随后我添加了一个实现,该实现从事件期间的所有响应(包括由 生成的动态响应)IHttpModule
中删除了不必要的响应标头(Server
、X-AspNet-Version
等)。IHttpHandler
PreSendRequestHeaders
但是,似乎简单地注册一个IHttpModule
,无论它实际做什么,都会导致 IIS 对响应应用压缩,即使响应已经被压缩。
因此,我IHttpHandler
明确压缩响应并设置Content-Encoding
标头,然后(当且仅当)IHttpModule
也注册了,IIS 重新压缩响应(因此存在浏览器无法读取的双重压缩响应)。
我不想禁用所有默认压缩。我仍然希望视图中的 HTML 被压缩(并且我希望任何不通过的 CSS 和 JSIHttpHandler
也被默认压缩)。
我猜我的问题没有简单的解决方案,因为它似乎是 IIS 中的一个错误。IIS 不应压缩已压缩的响应。
我尝试将以下内容添加到我的 web.config 中,但没有效果:
<httpCompression>
<dynamicTypes>
<add mimeType="text/css" enabled="false" />
<add mimeType="application/javascript" enabled="false" />
</dynamicTypes>
</httpCompression>
(根据我对文档的解释,应该禁用动态生成的 CSS 和 JS 的压缩。)
我也试过这个,没有效果:
<httpCompression>
<dynamicTypes>
<clear/>
</dynamicTypes>
<staticTypes>
<clear/>
</staticTypes>
</httpCompression>
(根据我对文档的解释,应该禁用所有默认压缩。)
更新
在我的最后IHttpHandler
,我打电话context.Response.Flush
。如果我删除此调用,则响应不会被双重压缩。作为解决方案,我很好。谁能解释为什么会这样?
更新 2
我最好的猜测是调用Flush
会将响应置于 IIS 认为响应尚未压缩的状态(因此它会应用默认压缩)。即使在我的模块中我可以同时检查...
- 包含标题
Response.Headers
和Content-Encoding
- 那
Response.Filter
是非null
并且是其中一种System.IO.Compression
类型。
不知道为什么 IIS 无法确定响应已经从这些事实中压缩。