最近项目上有需求需要在小程序中跳转第三方网页,但微信业务域名限制了跳转,当聊到这个问题的时候马上就想到了nginx的反向代理。然后就进行了尝试。
nginx 版本为 1.12-alpine。
nginx配置反向代理
1 2 3 4 5 6 7 8 9
| server { ... location ^~ /testre/ { proxy_pass https://xxx.com/; } ... }
|
在nginx配置中添加代理,将访问 xxx.com 的所有链接代理到自己服务器的 /testre/* 路径下。然后在小程序中访问。
结果: 成功绕过域名限制,但css js 图片等资源加载失败,因为路径匹配不上。如 src=”/js/main.js”,因为匹配不到 /testre/ 路径,所以没有代理上。
修改响应以代理其它资源
为了解决这个问题,马上想到是否可以用 lua 在将资源返回到前端前进行内容的修改。但因为项目中使用的 nginx 镜像没有 lua-nginx-module ,我也无法对镜像进行修改,所以另寻它法。
使用 nginx -V 命令查看的时候,虽然没有发现 lua-nginx-module,但看到了 ngx_http_sub_module;该模块可以修改网站响应内容中的字符串达到我的目的。于是修改 nginx 配置文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| server { ... location ^~ /testre/ { proxy_pass https://xxx.com/; sub_filter_types *; sub_filter xxx.com myserver.com/testre; sub_filter 'src="/images/' 'src="/testre/images/'; sub_filter 'href="/css/' 'href="/testre/css/'; sub_filter 'src="/js/' 'src="/testre/js/'; sub_filter_once off; } ... }
|
然后访问,发现没有替换成功;网上搜索了一下发现了原因: xxx.com 开启了 gzip 压缩,而 ngx_http_sub_module 对压缩内容是匹配不到相应字符串的,于是加上请求头 Accept-Encoding “”。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| server { ... location ^~ /testre/ { proxy_set_header Accept-Encoding ""; proxy_pass https://xxx.com/; sub_filter_types *; sub_filter xxx.com myserver.com/testre; sub_filter 'src="/images/' 'src="/testre/images/'; sub_filter 'href="/css/' 'href="/testre/css/'; sub_filter 'src="/js/' 'src="/testre/js/'; sub_filter_once off; } ... }
|
结果: 页面大部分资源加载成功,还是有小部分资源加载失败。
查看这些加载失败的资源,发现是在 css 内部定义的,并且其 url 由 url(../ 变为了 url(../testre/ 。继续修改配置文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| server { ... location ^~ /testre/ { proxy_set_header Accept-Encoding ""; proxy_pass https://xxx.com/; sub_filter_types *; sub_filter xxx.com myserver.com/testre; sub_filter 'src="/images/' 'src="/testre/images/'; sub_filter 'href="/css/' 'href="/testre/css/'; sub_filter 'src="/js/' 'src="/testre/js/'; sub_filter url(../testre/ url(../; sub_filter_once off; } ... }
|
结果: 未替换成功。猜测还是 gzip 的原因。
在网上找到一个方法,反代理自身,利用 gunzip 模块先解压,然后再进行替换。修改配置文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| server { listen unix:/var/run/nginx-gunzip.sock; location / { proxy_set_header Accept-Encoding gzip; proxy_pass https://xxx.com/; gunzip on; access_log off; } }
server { ... location ^~ /testre/ { proxy_pass http://unix:/var/run/nginx-gunzip.sock:https://xxx.com/; sub_filter_types *; sub_filter xxx.com myserver.com/testre; sub_filter 'src="/images/' 'src="/testre/images/'; sub_filter 'href="/css/' 'href="/testre/css/'; sub_filter 'src="/js/' 'src="/testre/js/'; sub_filter url(../testre/ url(../; sub_filter_once off; } ... }
|
再访问结果即ok了。
参考链接