在 IIS8 中使用 Gzip 进行 Json HTTP 压缩

Posted

技术标签:

【中文标题】在 IIS8 中使用 Gzip 进行 Json HTTP 压缩【英文标题】:Json HTTP-Compression With Gzip In IIS8 【发布时间】:2012-11-27 15:15:32 【问题描述】:

好的,我已经阅读了好几个小时。数十个 SO 帖子和博客等。找不到答案。

目标:启用来自我的 WCF 服务的 json 响应的动态 http 压缩。

注意:当 applicationhost.config 包含以下内容时,gzip 已经适用于静态内容和动态内容:

<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
            <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
        <dynamicTypes>
            <add mimeType="text/*" enabled="true" />
            <add mimeType="message/*" enabled="true" />
            <add mimeType="application/x-javascript" enabled="true" />
            <add mimeType="application/json; charset=utf-8" enabled="true" />
            <add mimeType="*/*" enabled="false" />
        </dynamicTypes>
        <staticTypes>
            <add mimeType="text/*" enabled="true" />
            <add mimeType="message/*" enabled="true" />
            <add mimeType="application/x-javascript" enabled="true" />
            <add mimeType="application/atom+xml" enabled="true" />
            <add mimeType="application/xaml+xml" enabled="true" />
            <add mimeType="*/*" enabled="false" />
        </staticTypes>    
</httpCompression>
</system.webServer>

不幸的是,在我使用的服务器上,applicationhost.config 中缺少以下行:

<add mimeType="application/json; charset=utf-8" enabled="true" />

我无法手动添加它,因为服务器是由 Elastic Beanstalk 启动的 AWS EC2 实例(因此我可以在一个实例上更改它,但不是在所有实例启动时都更改它)。

不幸的是,applicationhost.config 包含这一行:

<section name="httpCompression" allowDefinition="AppHostOnly" overrideModeDefault="Deny" />

这意味着我无法覆盖我应用的 web.config 中的 httpCompression 部分。

我的问题:我应该尝试其他方法来启用动态内容的 gzip 压缩吗?

如果 overrideModeDefault="Allow" 那么我可以将 httpCompression 部分放在我的应用程序的 web.config 中并期望它覆盖吗?

如果需要,很高兴添加进一步的说明。

干杯

【问题讨论】:

我也在寻找同样问题的解决方案。 复制... ***.com/questions/4584956/… ***.com/questions/10795165/… 你是怎么解决你的问题的?? 大家好 - 更新线程,经过大量研究,似乎目前无法完成我上面描述的内容。障碍是 Beanstalk,使用香草 BS 部署,您无法运行影响所需设置的管理 cls。我们使用的是自定义 AMI,它有一个在系统启动时运行的进程——在这里我们更改了 apphost 文件。 HTH 【参考方案1】:

在这里聚会迟到了,但如果没有 AMI,这绝对是可能的。

创建一个 s3 存储桶来托管您的设置文件。在此示例中,我有一个名为 mys3bucket 的存储桶。将以下文件上传到mybucket/ebExtensions/setup.ps1下的bucket

此文件修改了根应用程序主机配置。

write-host "Applying IIS configuration ..."

$globalConfig = "C:\Windows\System32\inetsrv\config\applicationHost.config"

$xmlDoc = new-object System.Xml.XmlDocument

$xmlDoc.Load($globalConfig)

#Set minimum compression size
write-host "Setting minimum compression size ..."
$xmlCurrentNode = $xmlDoc.SelectSingleNode("/configuration/system.webServer/httpCompression")
if ($xmlCurrentNode -eq $null)

    $xmlCurrentNode = $xmlDoc.CreateElement("httpCompression")
    $xmlDoc.SelectSingleNode("/configuration/system.webServer").AppendChild($xmlCurrentNode)

$xmlCurrentNode.SetAttribute("minFileSizeForComp", "10240")
$xmlCurrentNode.SetAttribute("dynamicCompressionEnableCpuUsage", "70")
write-host "Done."

#Enable dynamic compression
write-host "Enabling dynamic compression ..."
$xmlCurrentNode = $xmlDoc.SelectSingleNode("/configuration/system.webServer/urlCompression")
if ($xmlCurrentNode -eq $null)

    $xmlCurrentNode = $xmlDoc.CreateElement("urlCompression")
    $xmlDoc.SelectSingleNode("/configuration/system.webServer").AppendChild($xmlCurrentNode)

$xmlCurrentNode.SetAttribute("doDynamicCompression", "true")
write-host "Done."

#Add dynamic types for compression
write-host "Adding dynamic types ..."
$xmlCurrentNode = $xmlDoc.SelectSingleNode("/configuration/system.webServer/httpCompression/dynamicTypes")
if ($xmlCurrentNode -eq $null)

    $xmlCurrentNode = $xmlDoc.CreateElement("dynamicTypes")
    $xmlDoc.SelectSingleNode("/configuration/system.webServer/httpCompression").AppendChild($xmlCurrentNode)

$xmlCurrentNode = $xmlDoc.SelectSingleNode("/configuration/system.webServer/httpCompression/dynamicTypes/add[@mimeType='application/*']")
if ($xmlCurrentNode -eq $null)

    $xmlCurrentNode = $xmlDoc.CreateElement("add")
    $xmlCurrentNode.SetAttribute("mimeType", "application/*")
    $xmlDoc.SelectSingleNode("/configuration/system.webServer/httpCompression/dynamicTypes").AppendChild($xmlCurrentNode)

$xmlCurrentNode.SetAttribute("enabled", "true")
write-host "Done."

write-host "Saving the target config file ..."
$xmlDoc.Save("$globalConfig")
write-host "Done."

接下来你需要在你的项目中使用elastic beanstalk extensions。

将以下 init.config 文件添加到网站根目录下的 .ebextensions 文件夹中。这是一个 YAML 文件,所以使用空格缩进而不是制表符。

files:
  "c:/cfn/init.ps1":
    content: |
      $instanceDoc = Invoke-RestMethod 'http://169.254.169.254/latest/dynamic/instance-identity/document'
      $extPath = "c:\cfn\.ebextensions"
        if (Test-Path $extPath) 
          Remove-Item $extPath -Recurse
        
      Read-S3Object -BucketName "mys3bucket" -Folder $extPath -KeyPrefix '/ebExtensions' -Region ($instanceDoc.region)
      . (Join-Path $extPath -ChildPath '\setup.ps1')
container_commands:
  00-invoke-init:
    command: powershell.exe -nologo -noprofile -file "c:\cfn\init.ps1"

确保您的实例通过角色有权访问存储桶,否则在调用 Read-S3Object 时传递 aws 凭据

上面执行以下操作

在 Files elastic beanstalk 事件中,名为 init.ps1 的新文件将被写入 c:\cfn\init.ps1 在 Commands 事件期间会执行 init.ps1 文件。 init.ps1 文件从 S3 下载设置文件并执行它。 (请注意,您可以将所有 powershell 内联,但这可以保持 YAML 干净,并且可以在以后的设置过程中更轻松地使用多个文件。)

【讨论】:

以上是关于在 IIS8 中使用 Gzip 进行 Json HTTP 压缩的主要内容,如果未能解决你的问题,请参考以下文章

GZIP是浏览器自动解压的吗?

在 WCF 中同时使用 JSON 和 gzip

如何在 Rails for Android 中使用 gzip 压缩 JSON?

使用 HttpClient、REST 和 gzip 读取 JSON

如何使用 AWS 胶水获取存储在 s3 中的模式或已处理的嵌套 json 文件压缩(gzip)?

MVC 4 - JSON ajax 动作结果的 GZIP 压缩 [重复]