Why Chrome prompts for downloading a page as a .gz

2019-04-07 13:42发布

问题:

I just discovered a very strange behaviour on Chrome while trying to accesss some pages. It will prompt to download them as .gz files instead of loading them.

This happens only with current Chrome and on all platforms.

When the page is properly loaded I can see this on the Inspector

Resource interpreted as Document but transferred with MIME type application/x-gzip: "https://confluence.example.com/display/engp/PR-1221".

I know that these are served by an nginx server which is configured to use gzip compression, but there is nothing wrong with this.

  gzip  on;  # that's on nginx part

I am almost sure this is something wrong with nginx configuration, but what?

What makes the problem even more interesting (and annoying) is that if you copy the URL from the hyperlink and paste it to the browser it will just open the page correctly. Yep, this happens only on hyperlinks.

I tried to find a bug report on chrome on this but the only thing I was able to find is that others did report a similar if not the same problem with reddit pages or github.com ones.

Request URL:https://confluence.example.com/display/engp/PR-1221
Request Method:GET
Status Code:200 OK
Request Headersview source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:UTF-8,*;q=0.5
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
DNT:1
Host:example.com
Referer:https://example.com/browse/PR-1221
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.152 Safari/537.22
Response Headersview source
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type
Access-Control-Allow-Methods:GET, POST, OPTIONS, HEAD
Access-Control-Allow-Origin:*
Baz:bah
Cache-Control:no-cache, must-revalidate
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/html;charset=UTF-8
Date:Mon, 04 Mar 2013 13:29:48 GMT
Expires:Thu, 01 Jan 1970 00:00:00 GMT
Foo:bar
Server:nginx/1.2.6
Transfer-Encoding:chunked
X-Confluence-Request-Time:1362403788150
X-Seraph-LoginReason:OK

回答1:

I experienced the same behavior and sent also a report to the chrome devs. Meanwhile I have disabled all of my chrome extensions and didn't recognize the behavior anymore. Feels kinda strange to me, because it works nice yesterday.

EDIT: I found the chrome causing extension. In my case it was "Hover Zoom". Any other installed extension (Adblock, PageSpeed, Tweetdeck and so on) works fine and without the "downloading .gz file" problem. The dev is working on that problem (https://code.google.com/p/hoverzoom/issues/detail?id=489)

EDIT2: I do not use HoverZoom anymore, because the extension is now spyware (take a look at https://code.google.com/p/hoverzoom/issues/detail?id=489#c16). Instead of Hover-Zoom I am now using Hover-Free (https://chrome.google.com/webstore/detail/hover-free/hcmnnggnaofmhflgomfjfbndngdoogkj/related). Hope that helps you. Thanks to Caschy (http://stadt-bremerhaven.de/chrome-erweiterung-hoverzoom-sendet-heimlich-daten/)



回答2:

Had this problem too. Found a solution by editing htaccess of my Wordpress site, forcing specific file types to load as is;

<IfModule mod_mime.c>
AddCharset utf-8 .html
AddCharset utf-8 .json
AddEncoding gzip .gz
</IfModule>
<FilesMatch "(\.html|\.html\.gz)$">
ForceType text/html
</FilesMatch>
<FilesMatch "(\.json|\.json\.gz)$">
ForceType text/javascript
</FilesMatch>

I think it's a problem of site's caching plugins. In my case, WPSuperCache



回答3:

I had the same problem and simply the Content-Type in the response header was wrong. To check the Content-Type goto the Network tab in Google Chrome's developer tools (F12) and see the Type columns. Most probably it's something like binary or gzip.

To solve your problem add two things to your NGINX configuration:

  1. I had pre-compressed files so had to make sure the server send the correct Content-Type (what on an Apache web server would be the ForceType directive). See How do I serve pre-gzipped files with nginx so that they'll be shown as text in the browser?

    You need the HttpGzipStatic module for this.

  2. Add gzip_vary on. See StackPath: Accept-Encoding: It's Vary Important:

    Imagine two clients: an old browser without compression, and a modern one with it. If they both request the same page, then depending on who sent the request first, the compressed or uncompressed version would be stored in the CDN. Now the problems start: the old browser could ask for a regular “index.html” and get the cached, compressed version (random junk data), or the new browser could get the cached, uncompressed version and try to “unzip” it. Bad news, either way.

    The fix is for the origin server to send back Vary: Accept-Encoding

References

  • How can I tell if my server is serving GZipped content?
  • What 'Content-Type' header to use when serving gzipped files?
  • Google Developers: Web Fundamentals: Optimizing Encoding and Transfer Size of Text-Based Assets
  • NGINX: Module ngx_http_gzip_module
  • NGINX: COMPRESSION AND DECOMPRESSION
  • Is Vary: Accept-Encoding overkill?