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.内容压缩导致替换不生效

参考: 反向代理sub_filter字符替换不生效

原因:

源站点启用了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级别中继承配置。

标签: Nginx

添加新评论