如何在反向代理中替换内容?How to replace content in reverse proxy?

内部问题链接数
0

方案概述

使用Nginx的http_sub_module对内容进行替换

方案实施

1. Nginx中的sub_module非默认安装,需要在编译前指定:

./configure --with-http_sub_module --with-http_ssl_module

执行完 configure 之后,可以按照常规依次执行 make & make install

2. 构建完成后,启动Nginx即可使用

。 使用的配置文件如下:

location / {
    proxy_pass https://xxxx;
    proxy_set_header Host xxx;
    sub_filter 'aa' 'bbbb';
}

3. 使用注意事项

3.1 注意内容替换的媒体类型(MIME types)选择

不熟悉以及不知道自己应该配置什么类似的,可以查看这份官方文档

类型
描述
典型示例
text
表明文件是普通文本,理论上是人类可读
text/plaintext/htmltext/css, text/javascript
image
表明是某种图像。不包括视频,但是动态图(比如动态 gif)也使用 image 类型
image/gifimage/pngimage/jpegimage/bmpimage/webpimage/x-iconimage/vnd.microsoft.icon
audio
表明是某种音频文件
audio/midiaudio/mpeg, audio/webm, audio/ogg, audio/wav
video
表明是某种视频文件
video/webmvideo/ogg
application
表明是某种二进制数据
application/octet-streamapplication/pkcs12application/vnd.mspowerpointapplication/xhtml+xmlapplication/xmlapplication/pdf

默认为 text/html ,例如如果需要替换css的内容,则要加 text/css,如果要加多个则用空格隔开。

配置样例如下:

location / {
    proxy_pass https://xxxx;
    proxy_set_header Host xxx;
    sub_filter 'aa' 'bbbb';

    sub_filter_types text/css;
}

3.2 注意替换次数,如果全局有多处地方要替换,则要配置参数 sub_filter_once

配置样例如下:

location / {
    proxy_pass https://xxxx;
    proxy_set_header Host xxx;
    sub_filter 'aa' 'bbbb';

    sub_filter_once off;
}

3.3 注意网页请求是否使用了gzip压缩传输,如果有需要关闭,否则Nginx中无法读取明文,也就无法进行文本替换

不熟悉gzip的可以查看维基百科有个大致的了解:

配置中通过proxy_set_header告诉源站无法接收压缩数据,请提供明文。配置中使用到了Accept-Encoding 这个字段,感兴趣的可以参考

location / {
    proxy_pass https://xxxx;
    proxy_set_header Host xxx;
    sub_filter 'aa' 'bbbb';

    proxy_set_header Accept-Encoding "";
}

4. 总结

综合上面的几个注意点,常用的配置参考如下:

location / {
    proxy_pass https://xxxx;
    proxy_set_header Host xxx;
    sub_filter 'aa' 'bbbb';

    proxy_set_header Accept-Encoding "";  # 关闭压缩
    sub_filter_types application/xml;     # 增加替换的媒体类型
    sub_filter_once off;                  # 全局替换,不止一次
}