飘在云端

啊!那蓝真天,白真云!

· 前端webServer · · 1301次浏览

nginx 反向代理保留传递参数跳转站外域名地址栏不变

有个需求,访问 www.example.com/api/?ver=c(参数不区分大小写)时需要跳转到 www.test.test/abc?test=123&config=%2fapi-test,同时地址栏还要保持不变,并且跳转的域名还含有参数,只能产生一次访问请求,也就是http状态码只能为200,不能触发重定向,需要对客户端完全透明无感知。

经过测试,发现需要做2个步骤,仅仅用rewrite只能实现站内域名的路径重写(服务器内部重写),而只用反向代理无法保留跳转前后不一样的参数,因此需要结合使用。

先用rewrite重写站内域名后面的路径部分及参数,再反代到需要跳转的域名。
如果没有地址栏保持不变这个硬性要求,可以简单粗暴的直接 return 301 跳转的站外域名,缺点是浏览器地址栏的域名发生了变化,同时还触发了用户端(浏览器)301/302重定向。

配置如下:

location /api/ {

if ($args ~* ^(.*)ver=c){

  # rewrite ^/(.*)$ /abc?test=123&config=%2fapi-test/$1 break;
    #如果不需要跳转前的参数附加到跳转后的参数,就去掉 $1
    rewrite ^/(.*)$ /abc?test=123&config=%2fapi-test break;
   proxy_pass https://www.test.test;

  }
}

实际效果会是这样:
地址栏保持不变,仍是原来的域名及其路径和参数, www.example.com/api/?ver=c,展现的内容实际却是 www.test.test/abc?test=123&config=%2fapi-test这个页面的内容

按F12查看网络请求,只产生了一次访问请求,http状态码为 200,并未有 301/302等其他状态码,对客户端完全透明无感知!

另外我这里踩了个坑,涉及到反向代理时,建议谷歌浏览器新建一个无痕窗口(快捷键 Ctrl + Shift + N)来测试,避免缓存等奇奇怪怪的因素导致调试时发现页面万年不变

在Firefox v91/chrome(Android webview)v93 上测试正常实现。

nginx 后台日志显示了也只显示了一次请求记录,返回 200 状态码 (nginx默认日志级别不记录内部重定向类型,即 rewrite )