Nginx 中使用 sub_filter 替换内容

Nginx 中使用 sub_filter 替换内容

在 iOS 环境中,点击网页上的输入框时,页面总是会被放大一些,输入完成后也不会自动复原,导致网页一直处于放大的状态,影响后续浏览。
解决方法是在返回的 HTML 内容中,修改 meta 标签,增加 user-scalable=no,禁止页面缩放:

1
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/>

但是有时候网页内容是开源软件提供的,例如 TrueNAS、Grafana 的登录页面,无法直接修改代码。因此需要在 Nginx 反向代理时,修改返回的 HTML 内容,达到禁止缩放的目的。
配置方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
location / {
# 省略无关配置

# 重要!
proxy_set_header Accept-Encoding '';

# 只对 text/html 类型的内容生效
sub_filter_types text/html;
# 只过滤一次,一般情况下只会有一处 <meta> 标签需要修改
sub_filter_once on;
# 将查找到的内容替换成带有禁止缩放的配置
sub_filter 'width=device-width, initial-scale=1' 'width=device-width, initial-scale=1, user-scalable=no';
}

需要注意的是:以上配置修改了请求头 Accept-Encoding,目的是防止被代理服务响应经过 Gzip 压缩的内容,因为 sub_filter 无法处理被压缩的内容,会替换失败。
如果一些服务忽略了 Accept-Encoding 请求头,强制返回压缩内容,可以考虑增加一层反向代理,在接收到压缩内容后,将不压缩的内容返回给最终的代理。