请教 Nginx 中对 application/json 格式进行 gzip 压缩无效的问题? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bombshell
V2EX    NGINX

请教 Nginx 中对 application/json 格式进行 gzip 压缩无效的问题?

  •  
  •   bombshell 2015-01-27 13:40:42 +08:00 15456 次点击
    这是一个创建于 3992 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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=0b019c20c14f05cd3db73afe18ca07902928889d; Path=/; httponly

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

    请问是哪里出了问题,找半天还是没找到。
    26 条回复    2015-01-29 12:04:06 +08:00
    ryd994
        1
    ryd994  
       2015-01-27 16:07:22 +08:00 via Android
    Content-Encoding: gzip
    这不就是压缩过了么!curl自动帮你解了而已
    bombshell
        2
    bombshell  
    OP
       2015-01-27 16:17:07 +08:00
    @ryd994 我用wget带Accept-Encoding头下下来的是文本格式,不是压缩包,照理说不应该是压缩包吗?我试过其他网站的下下来是压缩包。
    ryd994
        3
    ryd994  
       2015-01-27 16:25:14 +08:00 via Android
    其他网站上的content-type是什么?后缀是什么?
    BOYPT
        4
    BOYPT  
       2015-01-27 16:27:06 +08:00
    你程序里面不要输出Content-Encoding: gzip
    由nginx来处理。

    curl -v --compressed http:/xxxxxx > /dev/null

    这样只要你看到有Content-Encoding: gzip,说明就是压缩的。
    bombshell
        5
    bombshell  
    OP
       2015-01-27 16:42:31 +08:00
    @ryd994 比如https://api.github.com/events返回的是Content-Type: application/json; charset=
    bombshell
        6
    bombshell  
    OP
       2015-01-27 16:44:02 +08:00
    @BOYPT 我删掉web.header("Content-Encoding", "gzip")后是输出Content-Encoding: gzip没错,但是wget下来的依然是文本格式而且大小也没有压缩过,size有大于1k。
    bombshell
        7
    bombshell  
    OP
       2015-01-27 16:45:37 +08:00
    ryd994
        8
    ryd994  
       2015-01-27 17:05:12 +08:00 via Android
    不能啊,按照HTTP协议规范,设置了content-encoding就肯定得有相应的处理啊。
    ryd994
        9
    ryd994  
       2015-01-27 17:12:46 +08:00 via Android
    你用html文件试试看,如果html没问题的话,那就是gzip_types的问题 http://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_types

    你给个测试链接我看看,记得限制请求频率免得被人DOS了
    ryd994
        10
    ryd994  
       2015-01-27 17:14:12 +08:00 via Android
    等等,你是app里设定的gzip的header?
    不需要啊,nginx如果压缩了会自己设置的,不要在app里设
    clino
        11
    clino  
       2015-01-27 17:23:57 +08:00
    建议用wireshark抓包诊断比较快
    bombshell
        12
    bombshell  
    OP
       2015-01-27 17:27:53 +08:00
    @ryd994 我在本地测试的。。
    BOYPT
        13
    BOYPT  
       2015-01-27 17:41:46 +08:00
    @cruelcage 因为wget自动解压了呀,你纠结这个干嘛。
    bombshell
        14
    bombshell  
    OP
       2015-01-27 18:00:08 +08:00 via Android
    @BOYPT 不科学啊,没有压缩效果阿,照理说我加了accept-encodingwget不会解压阿
    ryd994
        15
    ryd994  
       2015-01-27 18:16:22 +08:00
    @BOYPT wget如果是手动设置header,不会解压,你可以用上面那个github的url试试

    @cruelcage 不要在python里设定content-encoding,让nginx自己来。如果有content-encoding,nginx就认为已经编码过了
    bombshell
        16
    bombshell  
    OP
       2015-01-27 18:51:26 +08:00 via Android
    @ryd994 我去掉了,效果一样。。
    ryd994
        17
    ryd994  
       2015-01-27 19:21:10 +08:00 via Android
    你用个本地文件先试试
    bombshell
        18
    bombshell  
    OP
       2015-01-27 20:35:37 +08:00
    @ryd994 我用curl -H "Accept-Encoding:gzip"得到的是gzip格式的了,然后再gunzip后正常,看来是wget自动解压缩了,坑爹,我要仔细研究下wget。感谢相助。
    bombshell
        19
    bombshell  
    OP
       2015-01-27 20:36:33 +08:00
    @ryd994 诶,不过为什么github的那个用wget就能正常得到gzip格式的呢,看来还是配置有问题。。
    zhicheng
        20
    zhicheng  
       2015-01-27 21:00:17 +08:00
    @ryd994 你需要再仔细的读一遍 RFC 了。

    gzip 并不是强制的,如果 client 不设置可以接收 gzip ,那么正常的 server 是不会发送 gzip 编码过的 body ,这是内容协商的一部分。
    ryd994
        21
    ryd994  
       2015-01-28 00:19:02 +08:00 via Android
    @zhicheng 问题是现在服务器有content-encoding这个header,却没有压缩
    ryd994
        22
    ryd994  
       2015-01-28 00:34:44 +08:00 via Android
    @zhicheng 事实证明楼主自己二了,不知道wget会自动解码
    zhicheng
        23
    zhicheng  
       2015-01-28 00:46:53 +08:00
    @ryd994 要不怎么叫内容协商呢?
    服务器端有,但是客户端没有发送支持 gzip 的 Accept-encoding ,服务器是不会压缩的。当然可以让服务器强制 gzip 压缩,只是默认服务器不会这样,违反 RFC 。
    另外那个 Content-Encoding 的头,是自己设置的。不是 Nginx 设置的。。。。
    bombshell
        24
    bombshell  
    OP
       2015-01-28 09:10:21 +08:00
    @zhicheng @ryd994 最终结果是这样

    有自己设置的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格式
    sampeng
        25
    sampeng  
       2015-01-28 13:58:19 +08:00
    gzip_min_length 1k;

    1k=1024个字节。你得json多大到1k啊。。

    补充一下,1k你就压缩,效率和压缩比反而低。

    json不需要gzip。除非上百k的。其他反而增加负担
    wuljy
        26
    wuljy  
       2015-01-29 12:04:06 +08:00
    1. 自己不要随意加头
    2. 小文件不要随意zip
    3. 大文件不要用json
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2333 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 05:15 PVG 13:15 LAX 21:15 JFK 00:15
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86