Nginx 通过sub_filter替换响应内容
sub_filter 属于 ngx_http_sub_module 模块,不是默认构建的,需要通过 --with-http_sub_module 配置参数启用。
配置示例
proxy_set_header Accept-Encoding ''; # 清除请求头中的Accept-Encoding,让后端服务器返回未压缩格式
sub_filter_types *; # 替换所有类型
sub_filter_once off; # 查找所有内容替换,而不是只替换一次
sub_filter 'old_address:8080' 'new_address:8888'; # 示例,将响应中的内容 old_address:8080 替换成 new_address:8888问题记录
1.内容压缩导致替换不生效
原因:
源站点启用了gzip压缩
解决方法:
添加
proxy_set_header Accept-Encoding '';2.proxy_set_header Accept-Encoding '';未生效
配置不生效
upstream sync-p2o-test {
server sync-p2o-test:8090;
}
server {
listen 8081 default_server;
server_name sync-p2o-test;
proxy_connect_timeout 600;
sendfile on;
proxy_read_timeout 600;
proxy_send_timeout 600;
client_max_body_size 300m;
tcp_nodelay on;
gzip on;
charset utf-8;
keepalive_timeout 60;
add_header Strict-Transport-Security "max-age=31536000";
# 替换所有响应中的 sync-p2o-test:8090 -> 192.168.1.100:8081
proxy_set_header Accept-Encoding "";
sub_filter_types *;
sub_filter_once off;
sub_filter 'sync-p2o-test:8090' '10.207.40.196:8081';
location / {
proxy_redirect off;
#proxy_set_header Host $http_host;
proxy_set_header Host 'sync-p2o-test:8090';
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
default_type application/json;
proxy_pass http://sync-p2o-test;
}
access_log /var/log/nginx/sync-p2o-test_access.log jsonlog;
error_log /var/log/nginx/sync-p2o-test_error.log;
}调整到location中恢复
upstream sync-p2o-test {
server sync-p2o-test:8090;
}
server {
listen 8081 default_server;
server_name sync-p2o-test;
proxy_connect_timeout 600;
sendfile on;
proxy_read_timeout 600;
proxy_send_timeout 600;
client_max_body_size 300m;
tcp_nodelay on;
gzip on;
charset utf-8;
keepalive_timeout 60;
add_header Strict-Transport-Security "max-age=31536000";
location / {
proxy_redirect off;
#proxy_set_header Host $http_host;
proxy_set_header Host 'sync-p2o-test:8090';
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
default_type application/json;
# 替换所有响应中的 sync-p2o-test:8090 -> 192.168.1.100:8081
proxy_set_header Accept-Encoding "";
sub_filter_types *;
sub_filter_once off;
sub_filter 'sync-p2o-test:8090' '192.168.1.100:8081';
proxy_pass http://sync-p2o-test;
}
access_log /var/log/nginx/sync-p2o-test_access.log jsonlog;
error_log /var/log/nginx/sync-p2o-test_error.log;
}原因:
参考: https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header
仅当当前级别上没有定义 proxy_set_header 指令时,这些指令才会从先前的配置级别继承。
也就是说当 location中没有定义proxy_set_header 指令时才会从server中继承。
当location级别和server级别都定义proxy_set_header的时候,仅location级别配置生效,且不从server级别中继承配置。