如何在Windows Azuredynamic内容上启用gzip HTTP压缩

我一直试图在我的Windows Azure托pipe的WCF Restful服务上启用gzip HTTP压缩失败,它仅从GET和POST请求返回JSON。

我已经尝试了很多东西,所以我很难列出所有这些东西,现在我意识到我一直在处理相互矛盾的信息(关于旧版本的azure等),所以最好从一个干净的石板开始!

我正在使用Visual Studio 2008,使用2010年2月的Visual Studio工具。

所以,根据以下链接 ..

HTTP压缩现在已经启用。 我在以下页面使用了build议(仅限于URL压缩build议)。

http://blog.smarx.com/posts/iis-compression-in-windows-azure

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

..但我没有得到压缩。 我不知道urlCompressionhttpCompression有什么不同。 我试图找出,但无济于事!

可能,事实上Visual Studio的工具是在支持压缩的Azure版本之前发布的,会是一个问题吗? 我已经阅读了一些地方,使用最新的工具,你可以select你想在发布时使用的Azure操作系统的版本…但是我不知道这是否是真的,如果是的话,我找不到select。 我可以使用预先启用http的版本吗?

我也尝试过HTTP压缩模块,但没有结果。

有没有人有关于如何实现这一目标的最新build议? 即与当前版本的Azure操作系统相关的build议。

干杯!

史蒂芬

更新:我编辑了上面的代码来修复web.config片段中的一个types。

更新2:使用下面答案中显示的whatsmyip URLtesting响应显示,我的service.svc中的JSON响应没有任何压缩就被返回,但静态HTML页面正在使用gzip压缩返回。 任何关于如何获得JSON响应压缩的build议将受到感谢!

更新3:尝试了大于256KB的JSON响应,以查看问题是否由于JSON响应小于此,如下面的评论中所述。 不幸的是,这个响应还没有被压缩。

那么花了长时间…但是我终于解决了这个问题,我想把任何正在挣扎的人的答案发给他。 解决scheme非常简单,我已经validation,它确实工作!

编辑您的ServiceDefinition.csdef文件以将其包含在WebRole标记中:

  <Startup> <Task commandLine="EnableCompression.cmd" executionContext="elevated" taskType="simple"></Task> </Startup> 

在您的networkingangular色中,创build一个文本文件并将其保存为“EnableCompression.cmd”

EnableCompression.cmd应该包含这个:

 %windir%\system32\inetsrv\appcmd set config /section:urlCompression /doDynamicCompression:True /commit:apphost %windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json; charset=utf-8',enabled='True']" /commit:apphost 

..就是这样! 完成! 这使得对webangular色返回的json进行dynamic压缩,我认为我在某处读取的MIMEtypes相当奇怪,所以请确保您完全复制代码。

至less我并不孤单 – 在一年之后,它仍然是一个愚蠢的PITA。

问题是一个MIMEtypes不匹配。 WCF使用Content-Type: application/json; charset=UTF-8返回JSON响应Content-Type: application/json; charset=UTF-8 Content-Type: application/json; charset=UTF-8 。 大约在该页面一半处的默认IISconfiguration不包括作为可压缩MIMEtypes。

现在,向你的web.config添加一个<httpCompression>部分,并添加application / json可能会很诱人。 但是,浪费一两个小时只是一个糟糕的方法 – 只能在applicationHost.config级别更改<httpCompression>元素。

所以有两种可能的解决scheme。 首先,您可以将您的WCF响应更改为使用默认configuration中可压缩的MIMEtypes。 text/json将工作,所以添加到您的服务方法(S)会给你dynamic压缩: WebOperationContext.Current.OutgoingResponse.ContentType = "text/json";

或者,您可以使用appcmd和启动任务更改applicationHost.config文件。 这是讨论(除其他事项)在这个线程 。 请注意,如果您添加该启动任务并在开发结构中运行它,它将会运行一次。 第二次,它会失败,因为你已经添加了configuration元素。 我最终创build了另一个具有单独的csdef文件的云项目,以便我的devfabric不会运行该启动脚本。 可能还有其他解决scheme。

更新

我对前一段中单独项目的build议并不是一个好主意。 非幂等的启动任务是一个非常糟糕的主意,因为有一天,Azure结构会决定为您重新启动angular色,启动任务将失败,并进入一个回收循环。 最有可能在半夜。 相反,让你的启动任务idempotent讨论在这个SO线程 。

为了处理首次部署后出现问题的本地开发结构,我将相应的命令添加到CMD文件中以重置configuration。 另外,我在这里专门设置了压缩级别,因为它在某些(所有?)情况下似乎默认为零。

 REM Remove old settings - keeps local deploys working (since you get errors otherwise) %windir%\system32\inetsrv\appcmd reset config -section:urlCompression %windir%\system32\inetsrv\appcmd reset config -section:system.webServer/httpCompression REM urlCompression - is this needed? %windir%\system32\inetsrv\appcmd set config -section:urlCompression /doDynamicCompression:True /commit:apphost REM Enable json mime type %windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json; charset=utf-8',enabled='True']" /commit:apphost REM IIS Defaults %windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='text/*',enabled='True']" /commit:apphost %windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='message/*',enabled='True']" /commit:apphost %windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/x-javascript',enabled='True']" /commit:apphost %windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='*/*',enabled='False']" /commit:apphost %windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"staticTypes.[mimeType='text/*',enabled='True']" /commit:apphost %windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"staticTypes.[mimeType='message/*',enabled='True']" /commit:apphost %windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"staticTypes.[mimeType='application/javascript',enabled='True']" /commit:apphost %windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"staticTypes.[mimeType='*/*',enabled='False']" /commit:apphost REM Set dynamic compression level to appropriate level. Note gzip will already be present because of reset above, but compression level will be zero after reset. %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"[name='deflate',doStaticCompression='True',doDynamicCompression='True',dynamicCompressionLevel='7',dll='%%Windir%%\system32\inetsrv\gzip.dll']" /commit:apphost %windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression -[name='gzip'].dynamicCompressionLevel:7 /commit:apphost 

MS的这篇文章是他们如何为JSON脚本http://msdn.microsoft.com/en-us/library/windowsazure/hh974418.aspx

它处理许多提到的问题,如能够处理Azure回收等

刚才有关于这个错误types183的问题,我find了一个解决scheme。 所以如果有其他人遇到这个问题,

这是我得到的错误:

用户程序“F:\ approot \ bin \ EnableCompression.cmd”用非零退出代码183退出。工作目录是F:\ approot \ bin。

这里是我修复它的代码:

 REM *** Add a compression section to the Web.config file. *** %windir%\system32\inetsrv\appcmd set config /section:urlCompression /doDynamicCompression:True /commit:apphost >> "%TEMP%\StartupLog.txt" 2>&1 REM ERRORLEVEL 183 occurs when trying to add a section that already exists. This error is expected if this REM batch file were executed twice. This can occur and must be accounted for in a Windows Azure startup REM task. To handle this situation, set the ERRORLEVEL to zero by using the Verify command. The Verify REM command will safely set the ERRORLEVEL to zero. IF %ERRORLEVEL% EQU 183 DO VERIFY > NUL REM If the ERRORLEVEL is not zero at this point, some other error occurred. IF %ERRORLEVEL% NEQ 0 ( ECHO Error adding a compression section to the Web.config file. >> "%TEMP%\StartupLog.txt" 2>&1 GOTO ErrorExit ) REM *** Add compression for json. *** %windir%\system32\inetsrv\appcmd set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json; charset=utf-8',enabled='True']" /commit:apphost >> "%TEMP%\StartupLog.txt" 2>&1 IF %ERRORLEVEL% EQU 183 VERIFY > NUL IF %ERRORLEVEL% NEQ 0 ( ECHO Error adding the JSON compression type to the Web.config file. >> "%TEMP%\StartupLog.txt" 2>&1 GOTO ErrorExit ) REM *** Exit batch file. *** EXIT /b 0 REM *** Log error and exit *** :ErrorExit REM Report the date, time, and ERRORLEVEL of the error. DATE /T >> "%TEMP%\StartupLog.txt" 2>&1 TIME /T >> "%TEMP%\StartupLog.txt" 2>&1 ECHO An error occurred during startup. ERRORLEVEL = %ERRORLEVEL% >> "%TEMP%\StartupLog.txt" 2>&1 EXIT %ERRORLEVEL% 

解决scheme可在http://msdn.microsoft.com/en-us/library/azure/hh974418.aspxfind

是的,你可以select你想要的操作系统,但默认情况下,你会得到最新的。

压缩是棘手的。 有很多事情可能会出错。 你有机会在代理服务器后面进行这个testing吗? 我相信默认情况下IIS不会将压缩内容发送给代理。 我find一个方便的工具来testing压缩是否正在工作,当我玩这个: http : //www.whatsmyip.org/http_compression/ 。

它看起来像你有doDynamicCompression =“假”…是只是一个错字? 如果您要从Web服务返回的JSON上进行压缩,那么您希望这样做。