功能上一切正常,但我担心所有来自后端服务器的响应都没有经过压缩就传输给了客户端(Web浏览器)。
设置如下:
- 后端服务器在内部域上,不对外开放。在
https://internal.app
上托管Web应用程序。
- 前端Web服务器使用IIS 7.5,托管主要的公共网站,并充当后端服务器的代理。主站点位于https://site.com
。我想以对客户端透明的方式将所有请求路由到
https://site.com/app/WHATEVER
到 https://internal.app/WHATEVER
。我的当前设置基于URL Rewrite 2.0和Application Request Routing IIS扩展。一般的方法基于以下文章的指南:
site.com
应用程序的相关 web.config
部分:
<system.webServer>
<rewrite>
<rules>
<rule name="Route the requests for backend app" stopProcessing="true">
<match url="^app/(.*)" />
<conditions>
<add input="{CACHE_URL}" pattern="^(https?)://" />
</conditions>
<action type="Rewrite" url="{C:1}://internal.app/{R:1}" />
<serverVariables>
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="RewriteBackendAbsoluteUrlsInResponse" preCondition="ResponseIsHtml1">
<match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^http(s)?://internal.app(\:80)?/(.*)" />
<action type="Rewrite" value="/app/{R:3}" />
</rule>
<rule name="RewriteBackendAbsoluteUrlsInRedirects" preCondition="ResponseIsHtml1">
<match serverVariable="RESPONSE_LOCATION" pattern="^http(s)?://internal.app(\:80)?/(.*)" />
<action type="Rewrite" value="/app/{R:3}" />
</rule>
<rule name="RewriteBackendRelativeUrlsInResponse" preCondition="ResponseIsHtml1">
<match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^/(.*)" negate="false" />
<conditions>
<add input="{URL}" pattern="^/app/.*" />
</conditions>
<action type="Rewrite" value="/app/{R:1}" />
</rule>
<rule name="RewriteBackendRelativeUrlsInRedirects" preCondition="ResponseIsHtml1">
<match serverVariable="RESPONSE_LOCATION" pattern="^/(.*)" negate="false" />
<conditions>
<add input="{URL}" pattern="^/app/.*" />
</conditions>
<action type="Rewrite" value="/app/{R:1}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<urlCompression dynamicCompressionBeforeCache="false" />
</system.webServer>
问题在于一旦我停止清除HTTP_ACCEPT_ENCODING服务器变量,每个与上述规则匹配的请求都以以下错误结束:
HTTP Error 500.52 - URL Rewrite Module Error. Outbound rewrite rules cannot be applied when the content of the HTTP response is encoded ("gzip")。
我知道这个线程,并按照那些说明进行操作。如上所示,我已经设置了dynamicCompressionBeforeCache="false"
,我已添加了必要的注册表项,并确保模块在IIS中正确排序。然而,这似乎仅在重写发生在一个Web应用程序内部时才起作用。如果我删除上述规则并添加一个简单的规则(和相应的出站规则)来重写例如
/x/WHATEVER
到/WHATEVER
,所有内容都可以正常工作,无需清除HTTP_ACCEPT_ENCODING
——规则有效,压缩对于重写请求是启用的。
但是,一旦我重新添加了重写响应到另一个Web应用程序的规则,并且我没有清除HTTP_ACCEPT_ENCODING
头,则相同的错误再次出现。
据我所知,如果重写涉及到另一个Web应用程序,则可以执行的操作会更受限制。例如,URL重写器必须从后端服务器接收未压缩的响应才能使用出站规则进行重写。我猜在这种情况下清除HTTP_ACCEPT_ENCODING
是必须的。
然而,我期望最终重写的响应应该被压缩,无论其来源于何处,因为压缩模块位于模块列表的顶部。看起来IIS做了一些捷径,直接将响应返回给客户端,绕过压缩模块。或者HTTP_ACCEPT_ENCODING
头被很快删除,以完全禁用压缩(不仅在服务器与服务器之间的通信中)。
因此,我的问题是:有没有一种方式可以压缩这些响应?
HttpCacheModule
和RewriteModule
与DynamicCompressionModule
和StaticCompressionModule
的关系是否重要? - Paul d'AoustHTTP_ACCEPT_ENCODING
标头保留为原样)。 - Paul d'Aoust