解决 sub_filter 不能替换 Gzip 过的内容

在微信小程序 web-view 跳转外部链接?甲方的需求千奇百怪,好在办法总比困难多。不是只允许业务域名吗,不大可能在别人网站放一个 txt 校验吧?此时反代不失为解决业务域名限制的一个办法,总之一切为目标服务。

⚠️ 就算绕开了限制,由于内容经你方服务器转发,你方也须承担责任。另请注意,撰文时个人类型的小程序暂不支持内嵌网页。本文假设我方域名 yourdomain.com,对方域名 example.com。

1) proxy_pass 转发下?感觉事情没那么简单。

location / {
    ...
    proxy_pass https://example.com;
    proxy_set_header Host example.com;
    proxy_set_header Referer https://example.com;
    ...
}
  1. 尝试修改绝对 URL,将对方域名变成我方域名,避免打开非业务域名。
location / {
    ...
    proxy_set_header Accept-Encoding '';

    sub_filter_types *;
    sub_filter_once off;
    sub_filter 'example.com' 'yourdomain.com';
    ...
}
  1. 有些网站无视 Accept-Encoding: '',不管三七二十一,统统返回压过的。sub_filter 又只能处理未经压缩的内容,所以替换失败。

先来看人家怎么办到的。第一个 location / 是对方 frontend 端的配置,向 upstream 请求压缩过的资料;第二个 location / 则是对方 backend 端的配置,开启 Gzip,并允许在 HTTP/1.0 压缩。

location / {
    ...
    proxy_set_header Accept-Encoding 'gzip';
    ...
}

前文提到,Nginx 默认以 HTTP/1.0 连接上游,偏偏 gzip_http_version 缺省值是 1.1,表现为对后端不启用 Gzip,所以…

location / {
    ...
    gzip on;
    gzip_http_version 1.0;
    ...
}
  1. 思路清晰了有没有?先解压、再替换就好了呗。前人留下许多牛掰的方法。Maxim Dounin 出于减省回源带宽的考量,写了个 gunzip filter 模块。姚伟斌又撸了个 patch,使 upstream 返回内容总是被解压。还有人直接修改 Nginx 源码以达到目的。

另一种 trick (感谢 ryd994 大大的原帖) 比较直观。做两次 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';
    ...
}

⚠️ 即使您在 Step 2 透过禁用压缩的方式顺利替换,也可以试看看 Step 4。这种需求很能吃出站流量,带宽嘛,总是省一点算一点。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值