问题:
我使用以下位置重写:
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
在所有这些情况下,$1
是123123
,重定向目标是/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
相关文章