技术解析

请教 Nginx 中对 application/json 格式进行 gzip 压缩无效的问题?
0
2021-05-26 17:01:53
idczone
nginx.conf

gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/json;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;


我用的是web.py框架
web.header("Content-Type", "application/json")
web.header("Content-Encoding", "gzip")


curl -I返回的是

HTTP/1.1 200 OK
Server: nginx
Date: Tue, 27 Jan 2015 05:32:34 GMT
Content-Type: application/json
Connection: keep-alive
Content-Encoding: gzip
Set-Cookie: webpy_session_id=0b019c20c1国外服务器4f05cd3db73afe18ca07902928889d; Path=/; httponly

wget --header="accept-encoding:gzip"之后得到的格式不是压缩格式

请问是哪里出了问题,找半天还是没找到。
Content-Encoding: gzip
这不就是压缩过了么!curl自动帮你解了而已

我用wget带Accept-Encoding头下下来的是文本格式,不是压缩包,照理说不应该是压缩包吗?我试过其他网站的下下来是压缩包。

其他网站上的content-type是什么?后缀是什么?

你程序里面不要输出Content-Encoding: gzip
由nginx来处理。
curl -v --compressed http:/xxxxxx > /dev/null
这样只要你看到有Content-Encoding: gzip,说明就是压缩的。

比如https://api.github.com/events返回的是Content-Type: application/json; charset=utf-8

我删掉web.header("Content-Encoding", "gzip")后是输出Content-Encoding: gzip没错,但是wget下来的依然是文本格式而且大小也没有压缩过,size有大于1k。

比如wget --header="Accept-Encoding:gzip" https://api.github.com/events和wget https://api.github.com/events结果一个是文本,一个是压缩包。

不能啊,按照HTTP协议规范,设置了content-encoding就肯定得有相应的处理啊。

你用html文件试试看,如果html没问题的话,那就是gzip_types的问题 http://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_types
你给个测试链接我看看,记得限制请求频率免得被人DOS了

等等,你是app里设定的gzip的header?
不需要啊,nginx如果压缩了会自己设置的,不要在app里设

建议用wireshark抓包诊断比较快

我在本地测试的。。

因为wget自动解压了呀,你纠结这个干嘛。

不科学啊,没有压缩效果阿,照理说我加了accept-encodingwget不会解压阿

wget如果是手动设置header,不会解压,你可以用上面那个github的url试试
不要在python里设定content-encoding,让nginx自己来。如果有content-encoding,nginx就认为已经编码过了

我去掉了,效果一样。。

你用个本地文件先试试

我用curl -H "Accept-Encoding:gzip"得到的是gzip格式的了,然后再gunzip后正常,看来是wget自动解压缩了,坑爹,我要仔细研究下wget。感谢相助。

诶,不过为什么github的那个用wget就能正常得到gzip格式的呢,看来还是配置有问题。。

你需要再仔细的读一遍 RFC 了。
gzip 并不是强制的,如果 client 不设置可以接收 gzip ,那么正常的 server 是不会发送 gzip 编码过的 body ,这是内容协商的一部分。

问题是现在服务器有content-encoding这个header,却没有压缩

事实证明楼主自己二了,不知道wget会自动解码

要不怎么叫内容协商呢?
服务器端有,但是客户端没有发送支持 gzip 的 Accept-encoding ,服务器是不会压缩的。当然可以让服务器强制 gzip 压缩,只是默认服务器不会这样,违反 RFC 。
另外那个 Content-Encoding 的头,是自己设置的。不是 Nginx 设置的。。。。

最终结果是这样
有自己设置的web.header("Content-Encoding", "gzip")后curl -I输出
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 28 Jan 2015 01:13:13 GMT
Content-Type: application/json
Connection: keep-alive
Content-Encoding: gzip
wget --header="accept-encoidng:gzip"返回文本格式
------------------------------------------------------------------------------------------------------------------------
去掉自己设置的web.header("Content-Encoding", "gzip")后curl -I输出:
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 28 Jan 2015 01:08:13 GMT
Content-Type: application/json
Connection: keep-alive
Vary: Accept-Encoding
wget --header="accept-encoidng:gzip"返回gzip格式

gzip_min_length 1k;
1k=1024个字节。你得json多大到1k啊。。
补充一下,1k你就压缩,效率和压缩比反而低。
json不需要gzip。除非上百k的。其他反而增加负担

1. 自己不要随意加头
2. 小文件不要随意zip
3. 大文件不要用json

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服