V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NGINX
NGINX Trac
3rd Party Modules
Security Advisories
CHANGES
OpenResty
ngx_lua
Tengine
在线学习资源
NGINX 开发从入门到精通
NGINX Modules
ngx_echo
skypyb
V2EX  ›  NGINX

nginx 反向代理 .js 到 .js.gz, 如何返回正确的响应头? 非静态文件, 使用 proxy_pass

  •  
  •   skypyb · 2021-03-31 00:40:56 +08:00 · 3009 次点击
    这是一个创建于 1315 天前的主题,其中的信息可能已经有所发展或是发生改变。

    使用 rewrite ^(.*)$ /$1.gz break; 来重写请求。 可以正常请求并返回。
    可就是返回的东西浏览器解析不了。

    因为 content-type 值会为 application/gzip, 我想让他变为我想要的, 试过了各种方法都没用.. 就很难受。

    折腾好久, 不知道怎么搞了,Nginx gzip_static 模块似乎只能对静态文件生效, 我这场景是访问对象储存里边的资源。

    location ~* ^.+\.(css|js)$ {
    
    	rewrite ^(.*)$ /$1.gz break;
                    
    	#下面是试过的东西, 全都没用
    	#gzip_static on;
    
    	#default_type application/javascript;
    
    	#types {
    	#       application/javascript gz;
    	#}
                    
    	#add_header content-type application/javascript
    
    	proxy_pass https://cos;
    	proxy_redirect default;
    
    	#......
    
    }
    
    11 条回复    2021-03-31 12:57:19 +08:00
    ETiV
        1
    ETiV  
       2021-03-31 01:02:08 +08:00
    curl -v 看一下,是不是多发了 content-type 头

    不过为啥要这么做呢……感觉是个 X-Y problem
    skypyb
        2
    skypyb  
    OP
       2021-03-31 07:35:17 +08:00
    @ETiV 其实就是静态网站进行了一道 gz 后放在对象储存里, 然后想通过服务器反代一下。
    试了正常访问很正常。
    我想访问.gz 后缀的文件 (存在) 并返回正确的 conntent-type 和 content-encoding, 用 Nginx 没找到怎么弄..

    之所以要这样弄, 主要是不想打包后还要去手动上传到服务器, 直接 serverless 一行命令传到对象储存里就很方便
    Firxiao
        3
    Firxiao  
       2021-03-31 07:55:22 +08:00 via Android
    Nginx 只是做了透传,如果没有相关配置,并不会改变后端服务器传回来的 header 。
    建议
    1,直接访问后端看 header 是否正常
    2,检查其他地方是不是有针对 js 的 gzip 配置
    3,可以尝试 proxy_set_header
    eason1874
        4
    eason1874  
       2021-03-31 08:14:41 +08:00
    你 rewrite 下面的代码已经没有机会执行了,怎么改都是徒劳,因为你的 rewrite 已经全量重写到 .gz 后缀,而你这个 location 只匹配 .css 和 .js 后缀。

    使用本地的预压缩文件很简单。这样配置,访问 /test.css 的时候 Nginx 会先去找 test.css.gz ,如果有就返回,无则找 test.css 返回。

    location = /test.css {
    gzip_static on;
    gunzip on;
    }

    但是反代这样配置就不行(不确定支不支持,我不知道原因)。

    如果你确定请求路径在后端一定有 gz 文件,你可以重写路径,定向到 gz 文件并添加一个 content-encoding=gzip 的 header,这样就能返回预压缩文件给客户端。

    rewrite /test.css /test.css.gz break;
    location = /test.css.gz {
    proxy_pass https://cos;
    add_header "content-encoding" "gzip";
    }

    但也有个问题,这样不兼容不支持 gzip 的客户端,要兼容,你得先判断客户端 Accept-Encoding 有没有 gzip,如果没有还是得另外返回原文。

    用对象存储做后端最方便的还是对象存储放未压缩的 css/js 文件,前端 Nginx proxy 的时候开启 gzip on 就好了,反正是静态文件,可以设置 proxy_cache 读取一次就缓存在本地。
    lookookok
        5
    lookookok  
       2021-03-31 08:46:25 +08:00 via iPhone
    @eason1874
    对的。再建议加个 Vary: Accept-Encoding 头

    proxy 使用 rewrite 完成 gzip 会增加复杂程度,不确定客户端的兼容性,不建议这么搞。

    还是建议使用 nginx 原声模块实现 gzip 稳妥。
    dongtingyue
        6
    dongtingyue  
       2021-03-31 09:42:13 +08:00
    对象存储这样用的?没提供域名访问的么?
    dany813
        7
    dany813  
       2021-03-31 09:43:45 +08:00
    ng 不是可以开启 gzip 压缩吗
    Firxiao
        8
    Firxiao  
       2021-03-31 10:16:07 +08:00
    先不讨论是否使用 Nginx 做压缩.
    楼主的问题应该是通过 Nginx 给后端的返回增加或者更改 Header
    个人理解 最好还是后端服务控制 如果更改不了, 那就不要更改了. /狗头
    Firxiao
        9
    Firxiao  
       2021-03-31 10:27:45 +08:00
    另外对象存储是按请求量算钱的, 压缩后放对象存储问题不大.
    ddsfeng
        10
    ddsfeng  
       2021-03-31 10:34:13 +08:00
    proxy_pass 前面加一个 add_header Content-Encoding gzip; 声明一下 内容的 Encoding 即可
    skypyb
        11
    skypyb  
    OP
       2021-03-31 12:57:19 +08:00 via Android
    @eason1874 #4 谢谢指点, 我晚上回去试一下,不让 nginx 自己 gzip 主要是缓存了不方便刷新。 所以让他每次都走内网拿对象储存里的数据, 快+免费
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3172 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 12:27 · PVG 20:27 · LAX 04:27 · JFK 07:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.