Nginx——proxy_pass url 反向代理


 

說到 Nginx 就不得不說 Nginx 的反向代理是多么的好用,一個指令 proxy_pass 搞定反向代理,對於接口代理、負載均衡很是實用,但 proxy_pass 指令后面的參數很有講究。

在實際的應用中分為以下幾種情況:

 

1.url 只是 host

這里指不包含 $uri ,如:

  • http://host - √
  • https://host - √
  • http://host:port - √
  • https://host:port - √
  • http://host/ - x
  • http://host:port/ - x

這時候 location 匹配的完整路徑將直接透傳給 url ,如:

// 訪問:   /                               后端:   /
// 訪問:   /api/xx                         后端:   /api/xx
// 訪問:   /api/xx?aa                      后端:   /api/xx?aa
location / {
    proxy_pass http://node:8080;
}

// 訪問:   /api/                           后端:   /api/
// 訪問:   /api/xx                         后端:   /api/xx
// 訪問:   /api/xx?aa                      后端:   /api/xx?aa
// 訪問:   /api-xx?aa                      后端:
location /api/ {
    proxy_pass http://node:8080;
}

// 訪問:   /api/                           后端:   /api/
// 訪問:   /api/xx                         后端:   /api/xx
// 訪問:   /api/xx?aa                      后端:   /api/xx?aa
// 訪問:   /api-xx?aa                      后端:   /api-xx?aa
location /api {
    proxy_pass http://node:8080;
}

 

 

2.url 包含路徑

注意,這里的路徑哪怕只是一個 / 也是存在的,如:

  • http://host - x
  • https//host/ - √
  • http://host:port - x
  • https://host:port/ - √
  • http://host/api - √
  • http://host/api/ - √

當 proxy_pass url 的 url 包含路徑時,匹配時會根據 location 的匹配后的鏈接透傳給 url ,注意匹配后就是這樣:

location 規則 訪問的原始鏈接 匹配之后的路徑
location / /  
location / /a a
location / /a/b/c?d a/b/c?d
location /a/ /a/  
location /a/ /a/b/c?d b/c?d

明白匹配之后的路徑后,在 proxy_pass url 包含路徑時,將會把匹配之后的路徑透傳給 url ,如:

// 訪問:   /                               后端:   /
// 訪問:   /api/xx                         后端:   /api/xx
// 訪問:   /api/xx?aa                      后端:   /api/xx?aa
location / {
    proxy_pass http://node:8080/;
}

// 訪問:   /api/                           后端:   /
// 訪問:   /api/xx                         后端:   /xx
// 訪問:   /api/xx?aa                      后端:   /xx?aa
// 訪問:   /api-xx?aa                      未匹配
location /api/ {
    proxy_pass http://node:8080/;
}

// 訪問:   /api                            后端:   /
// 訪問:   /api/                           后端:   //
// 訪問:   /api/xx                         后端:   //xx
// 訪問:   /api/xx?aa                      后端:   //xx?aa
// 訪問:   /api-xx?aa                      后端:   /-xx?aa
location /api {
    proxy_pass http://node:8080/;
}

// 訪問:   /api/                           后端:   /v1
// 訪問:   /api/xx                         后端:   /v1xx
// 訪問:   /api/xx?aa                      后端:   /v1xx
// 訪問:   /api-xx?aa                      未匹配
location /api/ {
    proxy_pass http://node:8080/v1;
}

// 訪問:   /api/                           后端:   /v1/
// 訪問:   /api/xx                         后端:   /v1/xx
// 訪問:   /api/xx?aa                      后端:   /v1/xx
// 訪問:   /api-xx?aa                      未匹配
location /api/ {
    proxy_pass http://node:8080/v1/;
}

 

 

3.當 proxy_pass 遇到正則

當 location 以正則形式匹配時,proxy_pass 就不能以 / 結束了,也就是不能包含路徑了,比如錯誤的:

location ~* ^/api/ {
    proxy_pass http://host/;
}

location / {
    if ($uri ~* ^/api/) {
        proxy_pass http://host/;
    }
}

解決辦法就是把鏈接中的路徑去掉。

 

 

4.重寫代理鏈接 - url rewrite

 當原始鏈接(瀏覽器訪問的鏈接)和代理服務器鏈接規則不一致時,可以使用 Nginx URL Rewrite 功能去動態的重寫,如:

location ~* ^/api/ {
    rewrite ^/api/(.*) /?path=$1 break;
    proxy_pass http://node:8080;
}

以上請求會把匹配 /api/ 的鏈接重寫為 /?path= 的鏈接透傳給 node:8080 服務,有意思的是當使用 rewrite 指令並且生效后,proxy_pass url 鏈接中的路徑會被忽略,如:

// 訪問:   /                               后端:   /node/
// 訪問:   /api                            后端:   /node/api
// 訪問:   /api/                           后端:   /?path=
// 訪問:   /api/a/b/c                      后端:   /?path=a/b/c
location / {
    rewrite ^/api/(.*) /?path=$1 break;
    proxy_pass http://node:8080/node/;
}

 

 

 

參考:https://xuexb.github.io/learn-nginx/example/proxy_pass.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM