一、问题描述
nginx反向代理配置一般都是配置静态地址,比如:
server {listen 80;location / {proxy_pass http://myapp1;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;}}
这个反向代理表示访问80端口跳转到 http://myapp1 地址。
现在有需求代理的目的地址由动态传参决定,不能配置成静态的,传的参数为URL,然后反向代理到URL地址。
在配置过程中,会解决跳转后跨域问题和代理后地址自动拼接问题。
二、解决方案
1、nginx配置两个要跳转的地址作测试
地址一(index81.html 放在nginx/html/index81.html):
server {listen 81;server_name localhost;location / {root html;index index81.html index81.htm;}}
地址二(index82.html 放在nginx/html/index82.html):
server {listen 82;server_name localhost;location / {root html;index index82.html index82.htm;}}
2、动态代理配置
server {listen 80;server_name localhost;rewrite ^/old-url$ /new-url permanent;location /_proxy/ {# 通过正则截取路由中的 sub urlif ($request_uri ~* "/_proxy/(.*)") {set $proxy_url $1;}# 解析请求地址,并进行反向代理set $is_matched 0;if ($proxy_url ~* "^(http|ws)(s?):\/\/?([a-zA-Z0-9\-\.]+:?\d*)([^\?]*)") {set $is_matched 1;set $proxy_protocol http$2;set $proxy_host $3;set $proxy_uri $4;set $proxy_url $proxy_protocol://$proxy_host;rewrite ^ / break;proxy_pass $proxy_url;}}}
如代码所示,/_proxy 为代理匹配字符串,rewrite 作用有两点:
1、防止代理后的址带着 /_proxy 后边的路径。
2、浏览器的地址栏里地址不会变,还是127.0.0.1:80/....,这样就解决了跨域问题
最后,粘贴全部代码,包括注释等等
server {listen 80;server_name localhost;rewrite ^/old-url$ /new-url permanent;#charset koi8-r;#access_log logs/host.access.log main;location /_proxy/ {# 被代理路径为域名需要指定dns# resolver 114.114.114.114 valid=3600s;# 通过正则截取路由中的 sub urlif ($request_uri ~* "/_proxy/(.*)") {set $proxy_url $1;}# 解析请求地址,并进行反向代理set $is_matched 0;if ($proxy_url ~* "^(http|ws)(s?):\/\/?([a-zA-Z0-9\-\.]+:?\d*)([^\?]*)") {set $is_matched 1;set $proxy_protocol http$2;set $proxy_host $3;set $proxy_uri $4;set $proxy_url $proxy_protocol://$proxy_host;rewrite ^ / break;proxy_pass $proxy_url;}# if ($is_matched = 1) {# return 200 '{"code": 404, "message": "已经匹配到了!", "proxy_url": $proxy_url}';# }# if ($is_matched = 0) {# return 200 '{"code": 404, "message": "The proxy url is invalid!", "proxy_url": $proxy_url}';# }# Host 主机名,为了避免目标服务做限制此处采用目标地址的 Hostproxy_set_header Host $proxy_host;# X-Real-IP 将真实访问者的远端 IP 地址转发给代理服务器proxy_set_header X-Real-IP $remote_addr;# X-Forwarded-For 标记客户端通过代理连接到服务器的源 IPproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;# X-Forwarded-Host 标记客户端通过代理连接到服务器的原始主机proxy_set_header X-Forwarded-Host $host:$server_port;# X-Forwarded-Server 代理服务器的主机名proxy_set_header X-Forwarded-Server $host;# X-Forwarded-Port 定义客户端请求的原始端口proxy_set_header X-Forwarded-Port $server_port;# X-Forwarded-Proto 标记客户端通过代理连接到服务器的协议proxy_set_header X-Forwarded-Proto $scheme;# proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;}}
三、效果演示
http://127.0.0.1/_proxy/http://127.0.0.1:83
http://127.0.0.1/_proxy/http://127.0.0.1:82