Compressing a web service response for jQuery

2019-01-17 23:39发布

问题:

I'm attempting to gzip a JSON response from an ASMX web service to be consumed on the client-side by jQuery.

My web.config already has httpCompression set like so: (I'm using IIS 7)

<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files" 
    staticCompressionDisableCpuUsage="90" staticCompressionEnableCpuUsage="60" 
    dynamicCompressionDisableCpuUsage="80" dynamicCompressionEnableCpuUsage="50">
    <dynamicTypes>
        <add mimeType="application/javascript" enabled="true"/>
        <add mimeType="application/x-javascript" enabled="true"/>
        <add mimeType="text/css" enabled="true"/>
        <add mimeType="video/x-flv" enabled="true"/>
        <add mimeType="application/x-shockwave-flash" enabled="true"/>
        <add mimeType="text/javascript" enabled="true"/>
        <add mimeType="text/*" enabled="true"/>
        <add mimeType="application/json; charset=utf-8" enabled="true"/>
    </dynamicTypes>
    <staticTypes>
        <add mimeType="application/javascript" enabled="true"/>
        <add mimeType="application/x-javascript" enabled="true"/>
        <add mimeType="text/css" enabled="true"/>
        <add mimeType="video/x-flv" enabled="true"/>
        <add mimeType="application/x-shockwave-flash" enabled="true"/>
        <add mimeType="text/javascript" enabled="true"/>
        <add mimeType="text/*" enabled="true"/>
    </staticTypes>
    <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"/>
</httpCompression>
<urlCompression doDynamicCompression="true" doStaticCompression="true"/>

Through fiddler I can see that normal aspx and other compressions work fine. However, the jQuery ajax request and response work as they should, only nothing gets compressed.

What am I missing?

回答1:

You can change httpCompression only in applicationHost.config. See this link

Like you, I tried changing it in web.config first, but it didn't work. It worked only when I added the following lines to C:\Windows\System32\inetsrv\config\applicationHost.config:

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


回答2:

DO USE NOTEPAD to edit applicationHost.config. I've wasted several hours before understood that my changes made in notepad++ (as well as in Visual Studio 2010 editor!!) aren't applied by IIS.

Alternative way to add additional mimeType into dynamicTypes/staticTypes collection is to use appcmd. "C:\Windows\System32\Inetsrv\Appcmd.exe" set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/javascript',enabled='True']" /commit:apphost

And again: after these changes made - you'll see them only in notepad. Notepad++ (as well as Visual Studio 2010 editor!!) maintains some kind of f*ing alternate reality/storage for applicationHost.config. It shows you his own version of the file (different from the one you see in notepad) even after the file edited in notepad and reopened in np++/VS.



回答3:

Eric P's answer is mostly correct... you need to EXACTLY match the Content-Type header sent by IIS in its HTTP Response Headers. For some reason our IIS7 server was responding with: Content-Type: application/json; q=0.5

I had never ever observed a quality factor in a server response before. How bizarre.

When we added this to the dynamicTypes in the .config file everything started working:

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


回答4:

Changes in web.config don't work because of the following line in applicationHost.config:

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

If you replace it by:

<section name="httpCompression" overrideModeDefault="Allow" />

the changes are possible locally.

I think this is more convenient as you are able to configure every service differently and you don't have to edit your applicationHost.config if you must add a new MIME type.

Here is an example how to activate compression in web.config on a single ASMX service located in the service subfolder:

<location path="service/MySpecificWebService.asmx">
    <system.webServer>
        <httpCompression>
            <dynamicTypes>
                <add mimeType="application/json" enabled="true" />
                <add mimeType="application/json; charset=utf-8" enabled="true" />
            </dynamicTypes>
        </httpCompression>
        <urlCompression doDynamicCompression="true" />
    </system.webServer>
</location>

Concerning the actual editing of applicationHost.config, I suspect that it is not a true file in the file system. If you copy that file on your desktop, you will be able to edit it with any text editor, then copy it back to its original folder.



回答5:

http://forums.iis.net/t/1160210.aspx?missing+applicationhost+config

The config file is supposed to be %windir%\system32\inetsrv\config\applicationhost.config.

(Note that if your application (which is searching for applicationhost.config) is a 32bit app (for example, if you're using a 32bit CMD.EXE), then you won't be able to see the configuration file due to Windows SYSWOW32 redirection)

A bit of explanation regarding the missing applicationhost.config to change overrideModeDefault attribute to Allow. It's due to SYSWOW32 redirection.

Also you may not see the configuration files until you

  1. Open the folder by pasting "%windir%\system32\inetsrv\config\" exactly in the File Explorer location bar, and not your text editor
  2. Right-click and edit the file directly in that folder.

This is because for some reason some 64bit editors still use a faulty file-chooser dialog somehow.