如何防止对已压缩的响应进行默认 IIS 压缩?
TLDR
我有一个执行压缩的 IHttpHandler
。它本身工作得很好。但后来我添加了一个 IHttpModule,它对这些(以及所有其他)响应执行完全不相关的任务,现在 IIS 正在重新压缩已经压缩的响应。我怎样才能防止这种情况发生?
整个故事
我有一个 IHttpHandler
实现,它对 CSS 和 JS 文件执行组合和压缩(除其他外)。 IHttpHandler
中的所有内容都按照我想要的方式工作。
但后来我添加了一个 IHttpModule
实现,从 all 中删除不必要的响应标头(Server
、X-AspNet-Version
等) PreSendRequestHeaders
事件期间的 响应(包括由 IHttpHandler
生成的动态响应)。
然而,似乎简单地注册一个IHttpModule
,无论它实际做什么,都会导致 IIS 对响应应用压缩,即使响应已经被压缩。
因此,我的 IHttpHandler 显式压缩响应并设置 Content-Encoding 标头,然后(当且仅当)IHttpModule 也已注册, IIS 重新压缩响应(因此存在浏览器无法读取的双重压缩响应)。
我不想禁用所有默认压缩。我仍然希望视图中的 HTML 被压缩(并且我希望任何不经过 IHttpHandler 的 CSS 和 JS 也被默认压缩)。
我猜我的问题没有简单的解决方案,因为它看起来像是 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 无法根据这些事实确定响应已经被压缩。
TLDR
I have an IHttpHandler
that performs compression. It works fine on its own. But then I added an IHttpModule
that performs a completely unrelated task on those (and all other) responses, and now IIS is re-compressing the already-compressed responses. How can I prevent this?
The Whole Story
I have an IHttpHandler
implementation that performs combination and compression (among other things) for CSS and JS files. Everything in the IHttpHandler
works exactly like I want it to.
But then I added an IHttpModule
implementation that removes unnecessary response headers (Server
, X-AspNet-Version
, etc.) from all responses (including the dynamic responses that are generated by the IHttpHandler
) during the PreSendRequestHeaders
event.
However, it seems that simply registering an IHttpModule
, regardless of what it actually does, causes IIS to apply compression to the response, even if the response is already compressed.
So, my IHttpHandler
explicitly compresses the response and sets the Content-Encoding
header, then (if and only if) the IHttpModule
is also registered, IIS re-compresses the response (so there's a doubly-compressed response that browsers can't read).
I don't want to disable all default compression. I still want HTML from views to be compressed (and I want any CSS and JS that doesn't go through the IHttpHandler
to also be default-compressed).
I'm guessing there's no easy solution to my problem because it seems like a bug in IIS. IIS should not compress a response that is already compressed.
I tried adding the following to my web.config, but it had no effect:
<httpCompression>
<dynamicTypes>
<add mimeType="text/css" enabled="false" />
<add mimeType="application/javascript" enabled="false" />
</dynamicTypes>
</httpCompression>
(From my interpretation of the documentation, that should disable compression for dynamically generated CSS and JS.)
I also tried this, to no effect:
<httpCompression>
<dynamicTypes>
<clear/>
</dynamicTypes>
<staticTypes>
<clear/>
</staticTypes>
</httpCompression>
(From my interpretation of the documentation, that should disable all default compression.)
Update
In my IHttpHandler
, I call context.Response.Flush
at the very end. If I remove this call, the response doesn't get double-compressed. I'm fine with this as a solution. Can anyone explain why this is happening?
Update 2
My best guess is that calling Flush
puts the response into such a state that IIS doesn't think the response is already compressed (and so it applies default compression). Even though in my module I can check both...
- that
Response.Headers
contains aContent-Encoding
header and - that
Response.Filter
is non-null
and is one of theSystem.IO.Compression
types.
Not sure why IIS can't determine that the response is already compressed from those facts.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论