使用Nginx启用gzip压缩

35
我正在尝试为我的网站启用gzip压缩。我使用的是Ubuntu 11.04服务器和Nginx 1.2。
在我的网站的Nginx配置中,我有以下内容:
gzip on; #gzip_min_length 1000; gzip_http_version 1.1; gzip_vary on; gzip_comp_level 6; gzip_proxied any; gzip_types text/plain text/html text/css application/json application/javascript application/x-javascript text/javascript text/xml application/xml application/rss+xml application/atom+xml application/rdf+xml; #it was gzip_buffers 16 8k; gzip_buffers 128 4k; #my pagesize is 4 gzip_disable "MSIE [1-6]\.(?!.*SV1)";
Yslow和Google速度测量建议我使用gzip来减少网络传输。
现在当我尝试curl -I my_js_file时,我得到的结果是:
curl -I http://www.albawaba.com/sites/default/files/js/js_367664096ca6baf65052749f685cac7b.js HTTP/1.1 200 OK Server: nginx/1.2.0 Date: Sun, 14 Apr 2013 13:15:43 GMT Content-Type: application/x-javascript Content-Length: 208463 Connection: keep-alive Last-Modified: Sun, 14 Apr 2013 10:58:06 GMT Vary: Accept-Encoding Expires: Thu, 31 Dec 2037 23:55:55 GMT Cache-Control: max-age=315360000 Pragma: public Cache-Control: public Accept-Ranges: bytes
有没有想法,我做错了什么或者我应该做什么来获取压缩内容?

3
这是由这一行代码引起的吗:“gzip_http_version 1.1;”?如果将它改成“1.0”,会发生什么? - Chuan Ma
1
你最终搞清楚这个问题了吗? - Drew Khoury
2
@Drew,我刚刚把 gzip_http_version 1.1; 改成了 gzip_http_version 1.0; 然后它就可以工作了。 - Alaa
以下是有关编程的内容,请将其从英语翻译成中文。请仅返回已翻译的文本:您应该将其作为答案包含在内(并标记为已解决),以便他人可以从中受益。 - Drew Khoury
gzip_proxied any; 非常重要。 - Zhang Buzz
显示剩余4条评论
9个回答

33

正如其他人所写的那样,仅在服务器上启用gzip压缩是不够的--客户端还需要通过 Accept-Encoding: gzip 头部(或其子集)在请求中请求它。现代浏览器会自动包含此头部,但对于curl,您需要在命令中包含以下内容之一:

  • -H "Accept-Encoding: gzip":您应该会在响应中看到 Content-Encoding: gzip 头部(可能需要使用curl的 -v 标志输出标题),以及一些看起来杂乱无章的内容,实际上是gzip流。
  • --compressed:您仍然应该在响应头中看到 Content-Encoding: gzip,但是curl知道在输出之前解压缩内容。

4
奇怪的事情。我在AWS Ubuntu实例上安装的Nginx,在从浏览器发送请求时没有设置“Content-Encoding:gzip”头部。但是,当我使用“curl -H" Accept-Encoding: gzip "-I http://example.com”进行请求时,Nginx会正确设置“Content-Encoding:gzip”头部。为什么?尽管未设置头部,内容似乎已经被压缩。我通过Google的PageSpeed进行了检查,没有发现任何关于无gzip的问题。 - Green
很难说。不同的服务器在这方面有不同的逻辑,例如,某些服务器会从gzip编码中黑名单某些用户代理或内容类型。在其他情况下,它可能存在,但浏览器会将其隐藏起来,不让用户看到。所以这真的取决于具体情况。 :) - lot
我遇到了与@Green相同的问题,Nginx在日志中报告gzip压缩,对于CURL请求,我在响应中看到Content-Encoding: gzip头,但是当从浏览器发出请求时,在Chrome开发者工具的网络选项卡中没有看到该头。 - Marc

16

我无法明显发现您的配置中有任何问题,通常启用gzip和设置gzip_types为application/x-javascript就足以使其正常工作。如果一切顺利,您将收到返回“Content-Encoding:gzip”的内容。

请注意:我在使用谷歌开发者工具方面更具一致性(curl的行为方式与浏览器不同)。

在Chrome中,右键单击并转到“检查元素”,然后转到“网络”(如果需要,请重新加载页面),然后单击一个资源并检查标头选项卡,输出应如下所示(请注意,content-encoding为gzip,太好了):

Request URL:https://ssl.gstatic.com/gb/js/sem_a3becc1f55aef317b63a03a400446790.js
Request Method:GET
Status Code:200 OK (from cache)
Response Headersview source
age:199067
cache-control:public, max-age=691200
content-encoding:gzip
content-length:19132
content-type:text/javascript
date:Fri, 12 Apr 2013 06:32:58 GMT
expires:Sat, 20 Apr 2013 06:32:58 GMT
last-modified:Sat, 23 Mar 2013 01:48:21 GMT
server:sffe
status:200 OK
vary:Accept-Encoding
version:HTTP/1.1
x-content-type-options:nosniff
x-xss-protection:1; mode=block

无论如何,如果您确定您的内容没有被压缩,那么我通常会通过以下方式快速启动:

## Compression
gzip              on;
gzip_buffers      16 8k;
gzip_comp_level   4;
gzip_http_version 1.0;
gzip_min_length   1280;
gzip_types        text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript image/x-icon image/bmp;
gzip_vary         on;

你可以尝试使用此代码替换您的代码,并/或逐个调整值以帮助定位问题。

记得在更改配置后重新启动或重新加载nginx。

如果您仍然卡住了,检查日志并查看是否有任何有趣的东西可能也很有用。


两个测试工具,yslow和Google速度测试都显示我的组件没有被压缩... 请参考 https://developers.google.com/speed/pagespeed/insights#url=http_3A_2F_2Fwww.albawaba.com_2F&mobile=false - Alaa
你修改了配置并重新启动了Nginx吗?结果如何? - Drew Khoury
我确定我做了,它给出了相同的结果。 - Alaa
2
图像和 PDF 文件不应该被压缩,因为它们已经被压缩过了。试图对它们进行 gzip 压缩不仅浪费 CPU 资源,而且可能会增加文件大小。 - Adonis K. Kakoulidis
奇怪的事情。我在AWS Ubuntu实例上运行的Nginx,当我从浏览器发出请求时,不会设置Content-Encoding: gzip头文件。但是当我使用curl -H "Accept-Encoding: gzip" -I http://example.com命令时,Nginx可以很好地设置Content-Encoding: gzip头文件。为什么?而且尽管没有设置头文件,内容似乎已经被压缩了。我使用了Google的PageSpeed进行了检查,它并没有抱怨没有gzip。 - Green

12

我刚刚把 gzip_http_version 1.1; 改成了 gzip_http_version 1.0; 然后它就运行了。


4
这里需要说明的是,这个答案并不是一个适当的问题解决方案,更像是一种解决方法。将 gzip_http_version 设置为 1.0 可能会带来一些问题,想要了解更多信息,请阅读 https://serverfault.com/questions/418693/why-nginx-gzip-http-version-defaults-to-http-1-1。 - MBI

9

我需要在/etc/nginx/nginx.conf配置文件中启用gzip压缩:

gzip on;
gzip_disable "msie6";

gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;

请注意,我不得不将application/javascript添加到标准的gzip_types配置中。

7
这是我的nginx配置,它可以工作。
gzip                on;
gzip_min_length     1000;
gzip_buffers        4 8k;
gzip_http_version   1.0;
gzip_disable        "msie6";
gzip_types          text/plain text/css application/json application/javascript application/x-javasc    ript text/xml application/xml application/xml+rss text/javascript;
gzip_vary           on;

我认为关键点是gzipgzip_disablegzip_types

“gzip_disable, gzip_disable”是重复的,两个disable都很重要吗? - Melroy van den Berg
也许他是指其中一个需要开启gzip压缩? - Jonathan B.

5
你需要执行以下命令:
curl -I --compressed my_js_file

为使curl发送一个带有gzip的Accept-Encoding头部 - 只有当客户端发送一个表明它接受该头部的请求时,服务器才会压缩内容。

注意:你可以这样写:

gzip_disable "msi6"

不必使用正则表达式在IE 5.5和6中禁用,也不需要指定text/html类型,因为只要启用gzip,它总是被压缩。


curl --compressed --head http://www.albawaba.com/sites/default/files/js/js_367664096ca6baf65052749f685cac7b.js 返回: HTTP/1.1 200 OK Server: nginx/1.2.0 Date: Sun, 14 Apr 2013 16:59:34 GMT Content-Type: application/x-javascript - Alaa
我怀疑这不是完整的输出。你需要检查Content-Encoding头,而不是Content-Type。如果我在本地nginx服务器上使用curl --compressed命令,会得到"Content-Encoding: gzip",但如果我不包括--compressed选项,则没有Content-Encoding头。 - junichiro
另外,可能太明显了,但请确保在编辑配置文件后重新启动Web服务器。 - junichiro
我认为chue x已经给出了答案,但如果你想使用curl,仍然需要使用--compressed。 - junichiro

5
我猜测你可能需要增加gzip缓冲区大小。
以下是浏览器从该域名下载的文件。右侧数字为文件下载大小。

Files served from domain

您可能无法从屏幕截图中看出来,但所有文本内容文件都已经进行了gzip压缩,除了您在问题中提到的js文件。在屏幕截图中,js文件是绿色的,大小约为200K。这个文件大小大于您为gzip缓冲区指定的大小(128K)。 Gzip模块文档并没有很好地说明gzip缓冲区的用途(缓冲区是用于未压缩还是已压缩的数据)。然而,以下文章似乎表明缓冲区大小应大于未压缩文件大小:使用NGINX、GZip和SSL处理大文件

谢谢Chue,我已经提高了gizip_buffers(如上所示的问题[已编辑]),但仍然存在同样的问题,请告知您是否有任何想法。 - Alaa
顺便说一下,我真的很感激你的帮助,但是即使是 coutries_list,它的大小还不到128K,也没有被压缩成gzip格式... - Alaa
@Alaa - 你在countries_list没有被压缩的问题上是正确的。我漏掉了这一点。我有一个测试nginx设置,在那里我放置了两个文件,它们都被压缩了。我的gzip配置只有两行:gzip ongzip_types ...。此外,您的nginx服务器前面是否有代理缓存了这些文件?您可以尝试在nginx机器上运行curl(curl ... http://127.0.0.1/.../js_36..js)吗? - chue x
你应该检查响应是否包含头部 Content-Encoding: gzip - Flimm
最后一个链接“使用NGINX处理大文件”似乎无法工作。 - Fernando Gabrieli
@FernandoGabrieli 已修复。 - chue x

2

和Alaa一样,我不得不添加gzip_http_version 1.0;(之前没有指定版本),才能使其正常工作(我在Firefox 27.0.0上尝试过)。


1
我遇到了与Alaa相同的问题,问题是由于当前安装在我的计算机上的防病毒软件引起的。
代理服务器和防病毒软件可以在文件下载到客户端机器时禁用压缩。因此,如果您在使用此类防病毒软件或位于中间代理服务器后面(许多代理都是透明的,您可能甚至不知道代理介入了客户端和Web服务器之间),在浏览器中运行网站的客户端机器可能是此问题的原因。
禁用防病毒软件解决了我在浏览器中的问题,而且您甚至不需要将gzip_http_version设置为1.0。
希望这能帮到您。

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