IIS应用程序在响应头中缺少Content-Encoding - gzip

10

在Firebug中,请求头具有以下条目:
Accept-Encoding: gzip, deflate

但是在响应头中却没有:
Content-Encoding: gzip

尽管我尝试了许多Stack Overflow和其他网站上的答案,但似乎没有任何方法可以解决问题!无论是静态文件还是动态文件都没有被压缩,或者至少如果它们被压缩了,响应头中也没有回传gzip值的内容编码。

这是我的web.config设置示例:

<urlCompression doDynamicCompression="true" doStaticCompression="true" dynamicCompressionBeforeCache="true" />
<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files" minFileSizeForComp="150" staticCompressionIgnoreHitFrequency="true">
  <remove name="gzip" />
  <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" staticCompressionLevel="8" dynamicCompressionLevel="8" />
</httpCompression>

我忽略了命中频率:staticCompressionIgnoreHitFrequency="true"

我确认IIS实际上压缩了文件,我可以在这里看到:C:\inetpub\temp\IIS Temporary Compressed Files

如此指定:set up gzip in IIS 8 windows 8,我确保了Windows功能中启用了静态和动态压缩:Internet Information Services> WWW服务>性能特征

我还尝试了这位用户的方法:IIS 7.5 Compression creates compressed file but returns the non-compressed one


编辑1:
IIS版本为10,但我也在IIS 8.5上尝试过。


编辑2:
我现在也尝试了在此链接中找到的各种配置文件:https://github.com/h5bp/server-configs-iis/,这些文件提供了一些“最佳实践”web.config文件。
未解决


编辑3:
根据@Nkosi的建议,我创建了一个全新的Asp.net MVC应用程序,并使用我尝试过的所有选项进行了配置。 以下是我从Fiddler中得到的原始标头:

HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: text/javascript; charset=UTF-8
Expires: Wed, 20 Jul 2016 18:22:47 GMT
Last-Modified: Wed, 20 Jul 2016 18:22:47 GMT
Server: Microsoft-HTTPAPI/2.0
Date: Wed, 20 Jul 2016 18:22:47 GMT

正如您所看到的,没有 Content-Encoding: Gzip
未解决


编辑4:
我尝试了在 Global.asax 部分的 BeginRequest 事件中添加代码的方法:https://dev59.com/W18e5IYBdhLWcg3wlbTx#27185575
未解决


编辑5:
因此,我刚刚根据 SO 上的这个答案尝试启用跟踪:https://dev59.com/zlwX5IYBdhLWcg3w-Tlv#33182525
没有失败,但我注意到在跟踪文件的底部有一个名为 GENERAL_RESPONSE_HEADERS 的部分,下面是它提供的内容:

Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Server: Microsoft-IIS/10.0
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
X-Powered-By: My Little Pony
X-UA-Compatible: IE=Edge,chrome=1

这适用于每个静态类型文件。
然而,我在跟踪文件中找到了以下内容:

8. STATIC_COMPRESSION_START  08:04:03.552 
9. STATIC_COMPRESSION_NOT_SUCCESS Reason="NOT_FREQUENTLY_HIT" 08:04:03.552 
10. STATIC_COMPRESSION_END  08:04:03.552 

由于访问频率不高,压缩未成功...这很奇怪,因为我明确将忽略命中频率选项设置为true!

所以我进入了IIS管理器,并在服务器上将忽略命中频率设置为true(即applicationHost.config),这将更改跟踪文件输出如下:

8. STATIC_COMPRESSION_START  08:19:17.489 
9. STATIC_COMPRESSION_SUCCESS  08:19:17.489 
10. STATIC_COMPRESSION_END  08:19:17.489 

我回去将applicationHost.config中的设置关闭,结果返回到“Static Compression Not Success”,这肯定是有区别的。然而当我看FireBug时,它仍然传递未压缩的文件,没有GZIP Content Encoding响应头。

我在Failed Request Trace中注意到的另一个有趣的细节是,最后两个条目GENERAL_FLUSH_RESPONSE_END和GENERAL_REQUEST_END都显示我的Bootstrap.css文件已发送17903字节,大约18kb,与我在IIS临时压缩文件夹中看到的压缩版本的文件相匹配。所以文件实际上被压缩了,而且根据失败请求跟踪记录,它正在发送正确的内容......但是浏览器选择了完整的117kb文件?
未解决



我正在使用IIS10,我的web.config只有<urlCompression doDynamicCompression="true" doStaticCompression="true" dynamicCompressionBeforeCache="false" />。当我从浏览器(Firefox、IE11、Edge、Google Chrome)发送测试请求到一个简单的MVC应用程序时,所有请求都带有Accept-Encoding: gzip, deflate,响应返回Content-Encoding:gzip - Nkosi
请参考这里。也许您需要在服务器上启用gzip功能。 - Lucas Segers
@LucasSegers - 该功能肯定已启用。 - Jacques
@MakkyNZ,没有一个解决了我的问题。 - Jacques
@Jacques 正如MakkyNZ所提到的,最常见的原因是杀毒软件。我也遇到过这个问题好几次。 在所描述的场景中,服务器/响应方面似乎已经正确配置,因此看起来像是有东西解压缩了压缩文件。即使Fiddler也无法帮助,而Wireshark似乎可以帮忙(看起来它拦截了比杀毒软件更低级别的响应)。 一个快速简单的绕过杀毒软件的方法是,在使用https/SSL时检查内容是否被gzip压缩。 - Neven
显示剩余3条评论
3个回答

4

我在IIS和gzip配置方面也遇到了类似的问题。

在Firebug中,请求头具有以下条目: Accept-Encoding: gzip, deflate

但响应头中却没有:Content-Encoding: gzip

我的情况是由于杀毒软件保护造成的。实际上已经应用了gzipping,但启用了杀毒软件的http连接保护(取决于具体程序),它会解压缩响应并检查后再即时重写响应头。

注意:当某些代理/杀毒软件更改响应头时,一个关键属性是当Content-Length消失时,会添加Transfer-Encoding,其值为chunked


谢谢。你救了我的一天。Eset nod正在更改响应头并解压响应。 - AymAn AbuOmar
看起来反病毒程序截取了归档文件并在将其传递给浏览器之前将其解压缩,因此在此期间浏览器将始终接收未经压缩的文件。尝试在仅开启Windows Defender或关闭反病毒软件的计算机上进行测试,看看是否会得到内容编码。 - wnbates

1
我正在使用IIS10,我的web.config文件中有以下内容:
<system.webServer>
    <urlCompression doDynamicCompression="true" doStaticCompression="true" dynamicCompressionBeforeCache="false" />
    <!-- other config removed for brevity -->
</system.webServer>

当我在浏览器(Firefox、IE11、Edge、Google Chrome)中向一个简单的MVC应用程序发送测试请求时,这些请求都具有“Accept-Encoding: gzip, deflate”,而响应则返回“Content-Encoding:gzip”。我甚至使用Fiddler进行了测试。手动组合请求。
GET http://localhost/MyWebApplication HTTP/1.1
User-Agent: Fiddler
Host: localhost
Accept-Encoding: gzip, deflate

并获得相同的结果

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
Server: Microsoft-IIS/10.0
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 18 Jul 2016 15:26:06 GMT
Content-Length: 3826

...

Css、Js和其他基于文本的文件正在进行压缩。

您可能需要重新检查配置,以确保在IIS和您的web.config中正确配置了压缩。

更新:

我注意到图片没有被压缩。

请求

GET http://localhost/MyWebApplication/Images/Logo_small.png HTTP/1.1
User-Agent: Fiddler
Host: localhost
Accept-Encoding: gzip, deflate

响应
HTTP/1.1 200 OK
Cache-Control: max-age=604800
Content-Type: image/png
Last-Modified: Fri, 27 Nov 2015 03:15:22 GMT
Accept-Ranges: bytes
ETag: "c9d1fdd9c128d11:0"
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Mon, 18 Jul 2016 15:33:02 GMT
Content-Length: 2970

...

我通过一些谷歌搜索发现图片通常已经被压缩,因此没有应用gzip。 完整的web.config中的system.webServer部分
  <system.webServer>
    <urlCompression doDynamicCompression="true" doStaticCompression="true" dynamicCompressionBeforeCache="false" />
   <validation validateIntegratedModeConfiguration="false" />
    <httpErrors errorMode="Custom" existingResponse="Replace">
      <clear />
      <error statusCode="404" responseMode="ExecuteURL" path="/NotFound" />
    </httpErrors>
    <handlers>
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
    <staticContent>
      <remove fileExtension=".woff" />
      <remove fileExtension=".woff2" />
      <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
      <mimeMap fileExtension=".woff2" mimeType="application/font-woff2" />
      <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
    </staticContent>
  </system.webServer>

我已经更新了我的问题,请查看编辑3。你从示例中删除了哪些代码,是否有任何可能改变我的结果的内容? - Jacques
@Jacques,其余的配置是httpErrors,handler,staticContent。我保持了最小化。我会在更新中包含它。 - Nkosi
好的,我不认为这会影响到这个问题。我已经添加了另一个更新,尝试了另一个解决方案,但仍然没有成功。 - Jacques

0

我刚刚也遇到同样的问题。原因最终是由于 dynamicCompressionBeforeCache="true" 设置引起的。将该属性更改为 "false" 解决了该问题。

<urlCompression doDynamicCompression="true" doStaticCompression="true" dynamicCompressionBeforeCache="false" />

我在SmarterASP.Net提供的共享服务器上运行了几个网站。我向他们提出了一个支持工单,在此过程中,我确定dynamicCompressionBeforeCache="true"是罪魁祸首。

我指向了微软文档,涵盖了这个属性,链接为https://learn.microsoft.com/en-us/iis/configuration/system.webserver/urlcompression,并询问他们为什么设置为"true"会导致这个问题。

SmarterASP.Net支持引用了文档的一个部分,其中提到...

如果输出缓存响应已被刷新,则当dynamicCompressionBeforeCache属性为true时,动态压缩将不会在响应放入输出缓存之前执行。

...然后他们说...

“我们不在服务器端保存输出缓存。因此,输出缓存响应总是被刷新并导致了这个问题。”

我不能说我完全理解这里的机制,或者为什么SmarterASP.Net不保存输出缓存。但是,将dynamicCompressionBeforeCache="false"设置为肯定为我解决了问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接