|
简介:nginx做代理服务经常用到rewrite重写功能,其实在反向代理是可以更简单的方法达到重写url的效果。
一、原理说明
官方参考文档:https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/#passing-a-request-to-a-proxied-server
其行为规则如下:
当 proxy_pass 指令末尾包含斜杠(如 http://backend:8080/):
Nginx 会自动剥离 location 块中匹配的路径前缀,并将请求的剩余部分拼接到目标地址后。
例如:
location /api/ { proxy_pass http://backend:8080/; }
请求 /api/users → 转发为 http://backend:8080/users
当 proxy_pass 指令末尾不包含斜杠(如 http://backend:8080):
Nginx 会原样保留完整请求 URI,并将其拼接到目标地址后。
例如:
location /api/ { proxy_pass http://backend:8080; }
请求 /api/users → 转发为 http://backend:8080/api/users
location /some/path/ {
proxy_pass http://www.example.com/link/;
}
location /some/path/ {
proxy_pass http://www.example.com;
}
注意,在上述第一个例子中,代理服务器的地址后跟一个URI,。如果URI与地址一同指定,则替换了请求中与位置参数匹配的部分。/link/
例如,带有URI的请求将被代理到。然而,如果地址未指定URI,或者无法确定要替换的URI部分,则会传递完整请求URI(可能被修改)。
http://www.example.com/some/path/page.html --》 http://www.example.com/link/page.html
第二个例子就不会触发rewrite重写功能,访问效果:http://www.example.com/some/path/page.html --》 http://www.example.com/some/path/page.html
二、案例
http://tile-server:9100/后端服务的实际接口地址为:http://tile-server:9100/vdmp/tile/
1、触发rewrite配置。
location /vdmp/tile/ {
proxy_pass http://tile-server:9100/;
proxy_set_header Host $host;
}
2、访问测试
直接访问vdmp/tile/接口404,因为/vdmp/tile/前缀已经被剥离重写,不会传递到后端。
Warning: <FILE>" to s-test-64b784fc7d-xgbmw:/app# curl localhost/vdmp/tile/cities/tiles/9/428/209.pbf -i
HTTP/1.1 404 Not Found
Server: nginx
Date: Tue, 04 Aug 2026 11:00:45 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 19
Connection: keep-alive
Keep-Alive: timeout=10
Vary: Origin
X-Content-Type-Options: nosniff
404 page not found
在vdmp/tile/新增vdmp/tile/访问成功。
4fc7d-xgbmw:/app# curl localhost/vdmp/tile/vdmp/tile/cities/tiles/9/428/209.pbf -i
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 04 Aug 2026 11:00:17 GMT
Content-Type: application/x-protobuf
Content-Length: 1444
Connection: keep-alive
Keep-Alive: timeout=10
Content-Encoding: gzip
Vary: Origin
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
后端服务日志:
第一次测试日志:
{"time":"2026-08-04T10:59:25.762189655Z","id":"","remote_ip":"20.234.35.178","host":"localhost","method":"GET","uri":"/cities/tiles/9/428/209.pbf","user_agent":"curl/7.88.1","status":404,"error":"","latency":36494,"latency_human":"36.494µs","bytes_in":0,"bytes_out":19}
{"time":"2026-08-04T10:59:31.632029517Z","id":"","remote_ip":"20.234.35.178","host":"localhost","method":"GET","uri":"/cities/tiles/9/428/209.pbf","user_agent":"curl/7.88.1","status":404,"error":"","latency":28300,"latency_human":"28.3µs","bytes_in":0,"bytes_out":19}
第二次测试的日志:
{"time":"2026-08-04T10:59:50.609853597Z","id":"","remote_ip":"20.234.35.178","host":"localhost","method":"GET","uri":"/vdmp/tile/cities/tiles/9/428/209.pbf","user_agent":"curl/7.88.1","status":200,"error":"","latency":13782418,"latency_human":"13.782418ms","bytes_in":0,"bytes_out":1444}
{"time":"2026-08-04T11:00:02.688287401Z","id":"","remote_ip":"20.234.35.178","host":"localhost","method":"GET","uri":"/vdmp/tile/cities/tiles/9/428/209.pbf","user_agent":"curl/7.88.1","status":200,"error":"","latency":4032210,"latency_human":"4.03221ms","bytes_in":0,"bytes_out":1444}
{"time":"2026-08-04T11:00:17.945822669Z","id":"","remote_ip":"20.234.35.178","host":"localhost","method":"GET","uri":"/vdmp/tile/cities/tiles/9/428/209.pbf","user_agent":"curl/7.88.1","status":200,"error":"","latency":3708572,"latency_human":"3.708572ms","bytes_in":0,"bytes_out":1444}
|
