Nginx 1.13.8重寫url不能工作

分享于 

14分钟阅读

互联网

  简体

问题:

我使用以下位置重写:


location ~ ^/payment/gateway/v2/order/complete/(.*)$ {


 proxy_pass http://api.test.com:8080/payment/gateway/v2/order/complete?order_id=$1;


}



然后我尝试了这个:


 location /payment/gateway/v2/order/complete {


 rewrite ^/payment/gateway/v2/order/complete/(.+) /payment/gateway/v2/order/complete?order_id=$1 break;


 proxy_pass http://api.test.com:8080


}



然后这个:


 location /payment/gateway/v2/order/complete/ {


 rewrite ^/payment/gateway/v2/order/complete/$ /payment/gateway/v2/order/complete?order_id=$1 last;


 proxy_pass http://api.test.com:8080


}



然后这个:


location /payment/gateway/v2/order/complete {


 rewrite ^/payment/gateway/v2/order/complete/([^/]+)$ /payment/gateway/v2/order/complete?order_id=$1 last;


 proxy_pass http://api.test.com:8080;


}



他们都不管用。

编辑:这是完整的Nginx配置:


server {


 listen 443 ssl;


 server_name api.test.com www.api.test.com;



 ssl_certificate /home/ssl/api.test.com/cert.pem;


 ssl_certificate_key /home/ssl/api.test.com/key.pem;


 ssl_protocols SSLv3 TLSv1.2;


 ssl_ciphers "RC4:HIGH:!aNULL:!MD5:!kEDH";


 add_header Strict-Transport-Security 'max-age=604800';



 access_log /var/log/nginx/api.test.access.log;


 error_log /var/log/nginx/api.test.error.log;



 root /home/test;



 include /etc/nginx/conf/wellknown.conf;



 location /payment/paypal {


 proxy_pass http://api.test.com:8080;


 }



 location /payment/visa {


 proxy_pass http://api.test.com:8080;


 }



 location /payment/gateway {


 proxy_pass http://api.test.com:8080;


 }



 location /payment/gateway/order/complete {


 proxy_set_header Host $http_host;


 proxy_set_header Scheme $scheme;


 proxy_set_header SERVER_PORT $server_port;


 proxy_set_header REMOTE_ADDR $remote_addr;


 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;



 proxy_pass http://api.test.com:8080;


 }



 location /payment/gateway/v2/order/complete {


 rewrite ^/payment/gateway/v2/order/complete/(.+) /payment/gateway/v2/order/complete?order_id=$1 break;


 proxy_set_header Host $http_host;


 proxy_set_header Scheme $scheme;


 proxy_set_header SERVER_PORT $server_port;


 proxy_set_header REMOTE_ADDR $remote_addr;


 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;



 proxy_pass http://api.test.com:8080;


 }



 location /payment/mastercard/order {


 proxy_set_header Host $http_host;


 proxy_set_header Scheme $scheme;


 proxy_set_header SERVER_PORT $server_port;


 proxy_set_header REMOTE_ADDR $remote_addr;


 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;



 proxy_pass http://api.test.com:8080;


 }



 location /payment/mir/order {


 proxy_set_header Host $http_host;


 proxy_set_header Scheme $scheme;


 proxy_set_header SERVER_PORT $server_port;


 proxy_set_header REMOTE_ADDR $remote_addr;


 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;



 proxy_pass http://api.test.com:8080;


 }



 location /payment/v1 {


 proxy_pass http://api.test.com:8080;


 }



 location /catalog {


 proxy_set_header Host $http_host;


 proxy_set_header Scheme $scheme;


 proxy_set_header SERVER_PORT $server_port;


 proxy_set_header REMOTE_ADDR $remote_addr;


 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;



 proxy_pass http://localhost:9202; 


 }



 location / {


 if ($request_method = 'OPTIONS') {


 add_header 'Access-Control-Allow-Origin' '*';


 add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';


 add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,Locale';


 add_header 'Access-Control-Max-Age' 1728000;


 add_header 'Content-Type' 'text/plain charset=UTF-8';


 add_header 'Content-Length' 0;


 return 204;


 }


 if ($request_method = 'POST') {


 add_header 'Access-Control-Allow-Origin' '*';


 add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';


 add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';


 add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';


 }


 if ($request_method = 'GET') {


 add_header 'Access-Control-Allow-Origin' '*';


 add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';


 add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';


 add_header 'Access-Control-Expose-Headers' 'Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';


 }


 }



 location /test-rpc {


 proxy_pass http://api.test.com:8080;


 }


}



EDIT2:这里是wellknown.conf配置文件主体:


location ^~ /.well-known/ {


 default_type "text/plain";


 allow all;


}



EDIT3我优化了位置,但它不影响最终结果:


server {


 listen 443 ssl;


 server_name api.test.com www.api.test.com;



 ssl_certificate /home/ssl/api.test.com/cert.pem;


 ssl_certificate_key /home/ssl/api.test.com/key.pem;


 ssl_protocols SSLv3 TLSv1.2;


 ssl_ciphers "RC4:HIGH:!aNULL:!MD5:!kEDH";


 add_header Strict-Transport-Security 'max-age=604800';



 access_log /var/log/nginx/api.test.access.log;


 error_log /var/log/nginx/api.test.error.log;



 root /home/test;



 include /etc/nginx/conf/wellknown.conf;



 location /payment/gateway/v2/order/complete {


 rewrite ^/payment/gateway/v2/order/complete/(.+) /payment/gateway/v2/order/complete?order_id=$1 break;


 proxy_pass http://api.test.com:8085;


 } 



 location /payment {


 proxy_set_header Host $http_host;


 proxy_set_header Scheme $scheme;


 proxy_set_header SERVER_PORT $server_port;


 proxy_set_header REMOTE_ADDR $remote_addr;


 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;



 proxy_pass http://api.test.com:8085;


 }



 location /catalog {


 proxy_set_header Host $http_host;


 proxy_set_header Scheme $scheme;


 proxy_set_header SERVER_PORT $server_port;


 proxy_set_header REMOTE_ADDR $remote_addr;


 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;



 proxy_pass http://localhost:9202;


 }



 location / {


 if ($request_method = 'OPTIONS') {


 add_header 'Access-Control-Allow-Origin' '*';


 add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';


 add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,Locale';


 add_header 'Access-Control-Max-Age' 1728000;


 add_header 'Content-Type' 'text/plain charset=UTF-8';


 add_header 'Content-Length' 0;



 return 204;


 }



 if ($request_method = 'POST') {


 add_header 'Access-Control-Allow-Origin' '*';


 add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';


 add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';


 add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';


 }



 if ($request_method = 'GET') {


 add_header 'Access-Control-Allow-Origin' '*';


 add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';


 add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';


 add_header 'Access-Control-Expose-Headers' 'Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';


 }


 }



 location /test-rpc {


 proxy_pass http://api.test.com:8080;


 }


}



Nginx版本1.13.8


答案1:

可以在不使用rewrite命令的情况下完成。


location ~* /payment/gateway/v2/order/complete/(.+)$ {


 proxy_pass http://api.test.com:8085/payment/gateway/v2/order/complete?order_id=$1;


} 



在本例中,使用大小写不敏感的正规表达式(~* )来捕获URL之后的所有内容。

为了测试设置,我向Nginx添加了一个配置:


server {


 listen 80;


 server_name localhost;



 location ~* /payment/gateway/v2/order/complete/(.+)$ {


 proxy_pass http://localhost:8085/payment/gateway/v2/order/complete?order_id=$1;


 }



 location / {


 return 404;


 }


}



server {


 listen 8085;


 server_name localhost;


 location ~ /payment/gateway/v2/order/complete(.*) {


 return 202;


 }


}



这被配置成成功命中被代理到另一个服务器,并返回一个202,不成功的命中将导致40x响应。

可以通过curl进行测试,如下所示:


$ curl -v http://localhost:80/payment/gateway/v2/order/complete/1234 -L 


* Trying 127.0.0.1:80...


* TCP_NODELAY set


* Connected to localhost (127.0.0.1) port 80 (#0)


> GET /payment/gateway/v2/order/complete/1234 HTTP/1.1


> Host: localhost


> User-Agent: curl/7.68.0


> Accept: */*


> 


* Mark bundle as not supporting multiuse


< HTTP/1.1 202 Accepted


< Server: nginx/1.18.0 (Ubuntu)


< Date: Thu, 12 Nov 2020 02:02:12 GMT


< Content-Type: application/octet-stream


< Content-Length: 0


< Connection: keep-alive


< 


* Connection #0 to host localhost left intact



查看日志,我们观察了两个条目:


127.0.0.1 - - [12/Nov/2020:02:02:12 +0000] "GET /payment/gateway/v2/order/complete/1234 HTTP/1.1" 202 0 "-" "curl/7.68.0"




127.0.0.1 - - [12/Nov/2020:02:02:12 +0000] "GET /payment/gateway/v2/order/complete?order_id=1234 HTTP/1.0" 202 0 "-" "curl/7.68.0"



Nginx支持完整的PCRE用于匹配/设置表达式。


答案2:


location /payment/gateway/v2/order/complete {


 rewrite ^/payment/gateway/v2/order/complete/([^/]+)/? /payment/gateway/v2/order/complete/?order_id=$1? break;


 proxy_pass http://api.test.com:8080;


}



注意,我已经删除了结束字符串char $,并且添加了可选的尾部斜杠/?


/payment/gateway/v2/order/complete/123123


/payment/gateway/v2/order/complete/123123/


/payment/gateway/v2/order/complete/123123/whatever


/payment/gateway/v2/order/complete/123123/whatever?var=a



在所有这些情况下,$1123123,重定向目标是/payment/gateway/v2/order/complete/?order_id=123123

可以使用curl测试重定向:


curl -I https://yoursite/payment/gateway/v2/order/complete/123123/whatever/you/want/?var1=1&var2=b



你应该得到一个Location: https://yoursite/payment/gateway/v2/order/complete/?order_id=123123



URL  Nginx  重写  rewrite-url  
相关文章