nginx sub_filter 过滤及替换响应内容
查找并替换上游服务器的 Accept-Encoding 设为空值,以禁用压缩,是因为 sub_filter 只能处理未经压缩的内容;又 sub_filter 一般只替换 text/html 且仅工作一次,不符合需求,故对配置稍做微调。
1 2 3 4 5 6 7 8 |
location / { ... proxy_set_header Accept-Encoding ''; sub_filter_types *; sub_filter_once off; sub_filter 'a.com' 'b.com'; ... } |
有些网站无视 Accept-Encoding: '',sub_filter 又只能处理未经压缩的内容,所以替换失败。
第一个 location / 是对方 frontend 端的配置,向 upstream 请求压缩过的资料;第二个 location / 则是对方 backend 端的配置,开启 Gzip,并允许在 HTTP/1.0 压缩。
1 2 3 4 5 |
location / { ... proxy_set_header Accept-Encoding 'gzip'; ... } |
前文提到,Nginx 默认以 HTTP/1.0 连接上游,偏偏 gzip_http_version 缺省值是 1.1,表现为对后端不启用 Gzip,所以…
1 2 3 4 5 6 |
location / { ... gzip on; gzip_http_version 1.0; ... } |
做两次 proxy_pass,先反代源站 gzip 过的内容,再反代一次即可获得未压缩的内容。这里假设第一次的 location 在 forward 目录,第二次的在根目录。
⚠️ 上面的 gunzip on 和下面的 proxy_set_header Accept-Encoding '' 互为替代。
location /forward {
...
proxy_pass https://example.com;
# proxy_set_header Accept-Encoding 'gzip';
# gunzip on;
...
}
location / {
...
proxy_pass https://yourdomain.com/forward;
proxy_set_header Accept-Encoding '';
sub_filter_types *;
sub_filter_once off;
sub_filter 'example.com' 'yourdomain.com';
...
}