【问题标题】:enable gzip compression with nginx使用 nginx 启用 gzip 压缩
【发布时间】:2013-04-14 13:29:18
【问题描述】:

我正在尝试为我的网站组件启用 gzip 压缩。我有 ubuntu 11.04 服务器和 nginx 1.2。
在我网站的 nginx 配置中,我有这个

gzip打开; #gzip_min_length 1000; gzip_http_version 1.1; gzip_vary on; gzip_comp_level 6; gzip_proxied 任何; 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; #它是 gzip_buffers 16 8k; gzip_buffers 128 4k; #我的页面大小是 4 gzip_disable "MSIE [1-6]\.(?!.*SV1)";

Yslow 和谷歌速度测量建议我使用 gzip 来减少网络传输。 现在当我尝试curl -I my_js_file 我得到了

curl -I http://www.albawaba.com/sites/default/files/js/js_367664096ca6baf65052749f685cac7b.js HTTP/1.1 200 正常 服务器:nginx/1.2.0 日期:2013 年 4 月 14 日星期日 13:15:43 GMT 内容类型:application/x-javascript 内容长度:208463 连接:保持活动 最后修改时间:2013 年 4 月 14 日星期日 10:58:06 GMT 变化:接受编码 到期时间:格林威治标准时间 2037 年 12 月 31 日星期四 23:55:55 缓存控制:max-age=315360000 语用:公共 缓存控制:公共 接受范围:字节

知道我做错了什么或者我应该怎么做才能获得压缩内容?

【问题讨论】:

  • 这可能是由这条线引起的:gzip_http_version 1.1;?如果将其更改为 1.0 会发生什么?
  • 感谢 Chuna 的建议(竖起大拇指 :))现在虽然 curl -I 给出了相同的结果,但谷歌速度洞察力并没有给出警告
  • Google 仍然将albawaba.com/countries_list 提供为未压缩格式
  • 你最终解决了这个问题吗?
  • @Drew,我刚刚将 gzip_http_version 1.1; 更改为 gzip_http_version 1.0; 然后它就起作用了

标签: nginx gzip


【解决方案1】:

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

  • -H "Accept-Encoding: gzip" :您应该在响应中看到 Content-Encoding: gzip 标头(可能需要输出带有 curl 的 -v 标志的标头),以及一些看似乱码的内容输出,即实际的 gzip 流。
  • --compressed :您仍应在响应标头中看到 Content-Encoding: gzip,但 curl 知道在输出内容之前对其进行解压缩。

【讨论】:

  • 奇怪的东西。当我从浏览器发出请求时,我在 AWS Ubuntu 实例上的 Nginx 没有设置 Content-Encoding: gzip 标头。但是当我执行curl -H "Accept-Encoding: gzip" -I http://example.com 时,Nginx 设置Content-Encoding: gzip 标头就好了。为什么?尽管未设置标题,但内容似乎已被压缩。我检查了谷歌的 PageSpeed,它没有抱怨没有 gzip。
  • 很难说。各种服务器对此有不同的逻辑,例如一些来自 gzip 编码的某些用户代理或内容类型的黑名单。在其他情况下,它可能存在,但浏览器对用户隐藏了它。所以这真的取决于。 :)
  • 我遇到了与@Green 相同的行为,Nginx 在日志中报告 gzip 压缩,对于 CURL 请求,我在响应中看到 Content-Encoding: gzip 标头,但当请求来自浏览器,在 Chrome 开发者工具的网络标签中。
【解决方案2】:

我找不到您的配置有任何明显错误,通常 gzip on & gzip_types application/x-javascript 足以让您继续前进。如果一切正常,您将收到“Content-Encoding:gzip”返回给您。

请记住:我与 GOOGLE DEVELOPER TOOLS 的一致性更高(curl 的行为与浏览器不同)。

在 Chrome 中,右键单击并转到“检查元素”,然后转到“网络”(如果需要,请重新加载页面),然后单击资源并检查标题选项卡,输出应如下所示(注意内容编码是 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

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

## 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。

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

【讨论】:

【解决方案3】:

我只是将 gzip_http_version 1.1; 更改为 gzip_http_version 1.0; 然后它就起作用了

【讨论】:

  • 这里应该提到,这个答案不是正确的问题解决方案,它更有可能是解决方法。将 gzip_http_version 设置为 1.0 会带来一些问题,更多信息请阅读serverfault.com/questions/418693/…
【解决方案4】:

我必须在 /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 配置中。

【讨论】:

    【解决方案5】:

    你需要运行:

    curl -I --compressed my_js_file
    

    让 curl 为 gzip 发送一个 Accept-Encoding 标头 - 如果客户端发送一个标头说它会接受,服务器只会压缩内容。

    注意你可以写:

    gzip_disable "msi6"
    

    而不是在 IE 5.5 和 6 中使用正则表达式来禁用,并且您无需指定 text/html 作为类型,因为只要激活 gzip,它总是会被压缩。

    【讨论】:

    • curl --compressed --head albawaba.com/sites/default/files/js/… 提供:HTTP/1.1 200 OK 服务器:nginx/1.2.0 日期:星期日,2013 年 4 月 14 日 16:59:34 GMT 内容类型:应用程序/x-javascript
    • 我怀疑这不是完整的输出。它是您需要检查的 Content-Encoding 标头,而不是 Content-Type。如果我在本地 nginx 服务器上使用 curl --compressed,我会得到“Content-Encoding: gzip”,但如果我不包含 --compressed 选项,则没有 Content-Encoding 标头
    • 同样,可能太明显了,但请确保在编辑配置文件后重新启动 Web 服务器
    • 确定我重新启动了它 :),但正如您在 developers.google.com/speed/pagespeed/… 中看到的那样,谷歌速度分析器告诉我我的组件也没有压缩
    • 我认为 chue x 有答案,但如果你想使用 curl,你仍然需要使用 --compressed。
    【解决方案6】:

    我只是在这里猜测,但我认为您可能需要增加 gzip 缓冲区大小。

    以下是浏览器从域中提取的文件。右边的数字是文件下载大小。

    您可能无法从屏幕截图中看出,但所有文本内容文件都已压缩,除了您在问题中提到的 js 文件。截图中的js文件为绿色文件,大小约为200K。此文件大小大于您为 gzip 缓冲区指定的大小 (128K)。

    Gzip module docs 并没有很好地说明 gzip 缓冲区的用途(缓冲区是用于未压缩数据还是压缩数据)。但是,以下帖子似乎表明缓冲区大小应大于未压缩文件大小:Large files with NGINX, GZip, and SSL

    【讨论】:

    • 谢谢Chue,我已经提出了gizip_buffers(如上面的问题[编辑]),仍然是同样的问题,如果您有任何想法,请告知
    • 顺便说一句,我真的很感谢你的帮助,但即使 coutries_list 还没有被 gzip 压缩,虽然它小于 128K...
    • @Alaa - 你说的对 countries_list 没有被压缩是正确的。我错过了。我有一个测试 nginx 设置,我在其中放置了两个文件,并且它们都是 gzip 压缩的。我的 gzip 配置只有两行:gzip ongzip_types ...。另外,文件是否有可能被 nginx 服务器前面的代理缓存?可以在 nginx 机器上试试 curl(curl ... http://127.0.0.1/.../js_36..js)吗?
    • 你应该检查响应是否包含标题Content-Encoding: gzip
    • 最后一个链接“使用 NGINX 的大文件”似乎不起作用
    【解决方案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 "吗? 2x 禁用很重要吗?
    • 也许他的意思是gzip on 是其中之一?
    【解决方案8】:

    就像 Alaa 一样,我必须添加 gzip_http_version 1.0;(之前没有指定版本)才能工作(我在 Firefox 27.0.0 上尝试过)。

    【讨论】:

      【解决方案9】:

      我遇到了和 Alaa 一样的问题,问题是由我电脑上当前安装的杀毒软件引起的。

      当文件下载到客户端计算机时,代理服务器和防病毒软件可以禁用压缩。因此,如果您在使用此类防病毒软件的客户端计算机上的浏览器中运行网站,或者位于中间代理服务器后面(许多代理是透明的,您甚至可能不知道代理在您的客户端和 Web 服务器),它们可能是导致此问题的原因。

      禁用防病毒解决了我的浏览器问题,您甚至不需要将 gzip_http_version 设置为 1.0。

      希望对你有所帮助。

      【讨论】: