设置 IIS10 以提供预压缩文件
Setup IIS10 to serve pre-compressed files
我的 angular2 项目为我的网络应用构建了预压缩的 gzip 文件,但我的 IIS 只提供普通的“.js”文件,而不是压缩的“.gzip”文件。我的浏览器愿意接受 gzip。
IIS 允许 gzip 响应的正确设置是什么?
我已经搜索了 google/SO/SU,但只找到了不符合 "pre-compressed" 内容的解决方案。
经过长时间的搜索,我找到了 URL-Rewrite 的解决方法。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
<rewrite>
<rules>
<clear />
<rule name="Https redirect" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="^domain.com$" />
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
</rule>
<rule name="LetsEncrypt">
<match url=".well-known/acme-challenge/*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="None" />
</rule>
<rule name="Angular Routes" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
<rule name="br_rewrite" enabled="true" stopProcessing="true">
<match url="(.*).(js$|svg|css)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_ACCEPT_ENCODING}" pattern="br" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:1}.{R:2}.br" logRewrittenUrl="true" />
</rule>
<rule name="gzip_rewrite" enabled="true" stopProcessing="true">
<match url="(.*).(js$|svg|css)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_ACCEPT_ENCODING}" pattern="gzip" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:1}.{R:2}.gz" logRewrittenUrl="true" />
</rule>
</rules>
<outboundRules rewriteBeforeCache="true">
<rule name="Remove Server header" enabled="true">
<match serverVariable="RESPONSE_Server" pattern=".+" />
<action type="Rewrite" value="" />
</rule>
<rule name="Rewrite content-encoding header gzip" preCondition="IsGZ" enabled="true" stopProcessing="false">
<match serverVariable="RESPONSE_CONTENT_ENCODING" pattern=".*" />
<action type="Rewrite" value="gzip" />
</rule>
<rule name="Rewrite content-encoding header br" preCondition="IsBR" enabled="true" stopProcessing="false">
<match serverVariable="RESPONSE_CONTENT_ENCODING" pattern=".*" />
<action type="Rewrite" value="br" />
</rule>
<rule name="css content type" preCondition="IsCSS" enabled="true" stopProcessing="false">
<match serverVariable="RESPONSE_CONTENT_TYPE" pattern="(.*)" />
<action type="Rewrite" value="text/css" />
</rule>
<rule name="js content type" preCondition="IsJS" enabled="true" stopProcessing="false">
<match serverVariable="RESPONSE_CONTENT_TYPE" pattern="(.*)" />
<action type="Rewrite" value="application/javascript" />
</rule>
<rule name="svg content type" preCondition="IsSVG" enabled="true" stopProcessing="false">
<match serverVariable="RESPONSE_CONTENT_TYPE" pattern="(.*)" />
<action type="Rewrite" value="image/svg+xml" />
</rule>
<preConditions>
<preCondition name="IsGZ">
<add input="{URL}" pattern="\.gz$" />
</preCondition>
<preCondition name="IsBR">
<add input="{URL}" pattern="\.br$" />
</preCondition>
<preCondition name="IsCSS">
<add input="{URL}" pattern="css" />
</preCondition>
<preCondition name="IsJS">
<add input="{URL}" pattern="js" />
</preCondition>
<preCondition name="IsSVG">
<add input="{URL}" pattern="svg" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<urlCompression doStaticCompression="true" doDynamicCompression="false" />
<httpCompression sendCacheHeaders="false" />
<staticContent>
<mimeMap fileExtension=".br" mimeType="application/brotli" />
<clientCache cacheControlMode="UseMaxAge" />
</staticContent>
</system.webServer>
</configuration>
已成功处理 pre-build angular 文件(JS、CSS、SVG)的 BR 和 GZIP 请求。
我希望这对其他人有帮助。如果您知道更好的解决方案,请告诉我。
更简洁优雅的解决方案:
注意:文件扩展名 .gzip
看起来很奇怪,一般来说,我们将 gzip 文件命名为 .gz
,所以在这个例子中,我们使用 .gz
而不是 .gzip
, 如果你坚持.gzip
, 只需替换下面配置文件中的所有扩展。
先写代码,这就是我们所需要的 web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<staticContent>
<remove fileExtension=".js.gz" />
<remove fileExtension=".css.gz" />
<remove fileExtension=".png.gz" />
<remove fileExtension=".jpg.gz" />
<remove fileExtension=".gif.gz" />
<remove fileExtension=".svg.gz" />
<remove fileExtension=".html.gz" />
<remove fileExtension=".json.gz" />
<mimeMap fileExtension=".js.gz" mimeType="application/javascript" />
<mimeMap fileExtension=".css.gz" mimeType="text/css" />
<mimeMap fileExtension=".png.gz" mimeType="image/png" />
<mimeMap fileExtension=".jpg.gz" mimeType="image/jpeg" />
<mimeMap fileExtension=".gif.gz" mimeType="image/gif" />
<mimeMap fileExtension=".svg.gz" mimeType="image/svg+xml" />
<mimeMap fileExtension=".html.gz" mimeType="text/html" />
<mimeMap fileExtension=".json.gz" mimeType="application/json" />
</staticContent>
<rewrite>
<outboundRules rewriteBeforeCache="true">
<rule name="Custom gzip file header">
<match serverVariable="RESPONSE_CONTENT_ENCODING" pattern=".*" />
<conditions>
<add input="{REQUEST_URI}" pattern="\.gz$" />
</conditions>
<action type="Rewrite" value="gzip"/>
</rule>
</outboundRules>
<rules>
<rule name="Rewrite gzip file">
<match url="(.*)"/>
<conditions>
<add input="{HTTP_ACCEPT_ENCODING}" pattern="gzip" />
<add input="{REQUEST_FILENAME}.gz" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:1}.gz" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
而且,它是这样工作的:
为了实现成功的gzip数据传输,我们需要:
- 客户端接受 gzip 压缩数据,
Accept-Encoding
- 用 header 和
Content-Encoding
响应
- 正确的 MIME 类型,与原始文件相同,但不是
application/gzip
- Gzip 文件
四个条件必须同时满足
如果您使用 Content-Encoding: gzip
发送未压缩的文件,浏览器将 return 出错;
如果您发送的压缩文件没有 Content-Encoding
header,或者 MIME 类型不匹配,页面可能 return 一些 Zenith Star 的文本。
所以我们正在做的是:
- 重新定义每种 gzip 文件的 MIME
- 如果客户端接受 gzip 文件,则将响应文件直接重定向到服务器端的 gzip 版本(不是 302/303/307 响应)
- 重写
Content-Encoding
的响应header的header,仅当客户端发送headerAccept-Encoding
此解决方案适用于我的 IIS7,不确定它是否也适用于 IIS10。
如果您遇到任何问题,请告诉我:D
我的 angular2 项目为我的网络应用构建了预压缩的 gzip 文件,但我的 IIS 只提供普通的“.js”文件,而不是压缩的“.gzip”文件。我的浏览器愿意接受 gzip。
IIS 允许 gzip 响应的正确设置是什么?
我已经搜索了 google/SO/SU,但只找到了不符合 "pre-compressed" 内容的解决方案。
经过长时间的搜索,我找到了 URL-Rewrite 的解决方法。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
<rewrite>
<rules>
<clear />
<rule name="Https redirect" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="^domain.com$" />
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
</rule>
<rule name="LetsEncrypt">
<match url=".well-known/acme-challenge/*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="None" />
</rule>
<rule name="Angular Routes" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
<rule name="br_rewrite" enabled="true" stopProcessing="true">
<match url="(.*).(js$|svg|css)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_ACCEPT_ENCODING}" pattern="br" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:1}.{R:2}.br" logRewrittenUrl="true" />
</rule>
<rule name="gzip_rewrite" enabled="true" stopProcessing="true">
<match url="(.*).(js$|svg|css)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_ACCEPT_ENCODING}" pattern="gzip" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:1}.{R:2}.gz" logRewrittenUrl="true" />
</rule>
</rules>
<outboundRules rewriteBeforeCache="true">
<rule name="Remove Server header" enabled="true">
<match serverVariable="RESPONSE_Server" pattern=".+" />
<action type="Rewrite" value="" />
</rule>
<rule name="Rewrite content-encoding header gzip" preCondition="IsGZ" enabled="true" stopProcessing="false">
<match serverVariable="RESPONSE_CONTENT_ENCODING" pattern=".*" />
<action type="Rewrite" value="gzip" />
</rule>
<rule name="Rewrite content-encoding header br" preCondition="IsBR" enabled="true" stopProcessing="false">
<match serverVariable="RESPONSE_CONTENT_ENCODING" pattern=".*" />
<action type="Rewrite" value="br" />
</rule>
<rule name="css content type" preCondition="IsCSS" enabled="true" stopProcessing="false">
<match serverVariable="RESPONSE_CONTENT_TYPE" pattern="(.*)" />
<action type="Rewrite" value="text/css" />
</rule>
<rule name="js content type" preCondition="IsJS" enabled="true" stopProcessing="false">
<match serverVariable="RESPONSE_CONTENT_TYPE" pattern="(.*)" />
<action type="Rewrite" value="application/javascript" />
</rule>
<rule name="svg content type" preCondition="IsSVG" enabled="true" stopProcessing="false">
<match serverVariable="RESPONSE_CONTENT_TYPE" pattern="(.*)" />
<action type="Rewrite" value="image/svg+xml" />
</rule>
<preConditions>
<preCondition name="IsGZ">
<add input="{URL}" pattern="\.gz$" />
</preCondition>
<preCondition name="IsBR">
<add input="{URL}" pattern="\.br$" />
</preCondition>
<preCondition name="IsCSS">
<add input="{URL}" pattern="css" />
</preCondition>
<preCondition name="IsJS">
<add input="{URL}" pattern="js" />
</preCondition>
<preCondition name="IsSVG">
<add input="{URL}" pattern="svg" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<urlCompression doStaticCompression="true" doDynamicCompression="false" />
<httpCompression sendCacheHeaders="false" />
<staticContent>
<mimeMap fileExtension=".br" mimeType="application/brotli" />
<clientCache cacheControlMode="UseMaxAge" />
</staticContent>
</system.webServer>
</configuration>
已成功处理 pre-build angular 文件(JS、CSS、SVG)的 BR 和 GZIP 请求。
我希望这对其他人有帮助。如果您知道更好的解决方案,请告诉我。
更简洁优雅的解决方案:
注意:文件扩展名 .gzip
看起来很奇怪,一般来说,我们将 gzip 文件命名为 .gz
,所以在这个例子中,我们使用 .gz
而不是 .gzip
, 如果你坚持.gzip
, 只需替换下面配置文件中的所有扩展。
先写代码,这就是我们所需要的 web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<staticContent>
<remove fileExtension=".js.gz" />
<remove fileExtension=".css.gz" />
<remove fileExtension=".png.gz" />
<remove fileExtension=".jpg.gz" />
<remove fileExtension=".gif.gz" />
<remove fileExtension=".svg.gz" />
<remove fileExtension=".html.gz" />
<remove fileExtension=".json.gz" />
<mimeMap fileExtension=".js.gz" mimeType="application/javascript" />
<mimeMap fileExtension=".css.gz" mimeType="text/css" />
<mimeMap fileExtension=".png.gz" mimeType="image/png" />
<mimeMap fileExtension=".jpg.gz" mimeType="image/jpeg" />
<mimeMap fileExtension=".gif.gz" mimeType="image/gif" />
<mimeMap fileExtension=".svg.gz" mimeType="image/svg+xml" />
<mimeMap fileExtension=".html.gz" mimeType="text/html" />
<mimeMap fileExtension=".json.gz" mimeType="application/json" />
</staticContent>
<rewrite>
<outboundRules rewriteBeforeCache="true">
<rule name="Custom gzip file header">
<match serverVariable="RESPONSE_CONTENT_ENCODING" pattern=".*" />
<conditions>
<add input="{REQUEST_URI}" pattern="\.gz$" />
</conditions>
<action type="Rewrite" value="gzip"/>
</rule>
</outboundRules>
<rules>
<rule name="Rewrite gzip file">
<match url="(.*)"/>
<conditions>
<add input="{HTTP_ACCEPT_ENCODING}" pattern="gzip" />
<add input="{REQUEST_FILENAME}.gz" matchType="IsFile" />
</conditions>
<action type="Rewrite" url="{R:1}.gz" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
而且,它是这样工作的:
为了实现成功的gzip数据传输,我们需要:
- 客户端接受 gzip 压缩数据,
Accept-Encoding
- 用 header 和
Content-Encoding
响应
- 正确的 MIME 类型,与原始文件相同,但不是
application/gzip
- Gzip 文件
四个条件必须同时满足
如果您使用 Content-Encoding: gzip
发送未压缩的文件,浏览器将 return 出错;
如果您发送的压缩文件没有 Content-Encoding
header,或者 MIME 类型不匹配,页面可能 return 一些 Zenith Star 的文本。
所以我们正在做的是:
- 重新定义每种 gzip 文件的 MIME
- 如果客户端接受 gzip 文件,则将响应文件直接重定向到服务器端的 gzip 版本(不是 302/303/307 响应)
- 重写
Content-Encoding
的响应header的header,仅当客户端发送headerAccept-Encoding
此解决方案适用于我的 IIS7,不确定它是否也适用于 IIS10。
如果您遇到任何问题,请告诉我:D