今天上了一個多頁應用,發現接口轉發後是 401
。 最後發現是接口轉發出錯了。地址裏多拼了一個 路徑。 之前我一直覺得location 字段會替換掉 proxy_pass 裏面配置的 url 地址。 今天瞭解了一下 發現仍是有很多細節的。html
// node js 文件,打印請求路徑。方便查看後端真實接受到的請求地址 const http = require('http'); http.createServer((req, res) => { console.log(req.url); res.end(`您的 請求 地址是${req.url}`); }).listen(3000);
proxy_pass 如何轉發,首先看 proxy_pass 的url 配置。node
proxy_pass 只是HOST,不包含任何路徑,好比nginx
* http://host - √ * https://host - √ * http://host:port - √ * https://host:port - √ * http://host/ - x * http://host:port/ - x
這種狀況下,會把匹配到的全部路徑直接穿透轉發。好比如下的配置git
location /api/ { proxy_pass http://127.0.0.1:3000; }
訪問 http://127.0.0.1:80/api/cc
, 後端結果爲 您的 請求 地址是/api/cc
github
這裏的路徑哪怕只是一個 / 也是存在的,如:express
這種狀況下,url 裏面會去掉 location
匹配的字符串,拼接到 proxy_pass 再進行轉發。後端
location /api/ { proxy_pass http://127.0.0.1:3000/; }
訪問 http://127.0.0.1:81/api/cc
, 後端結果爲 您的 請求 地址是/cc
api
使用 rewrite 指令而且生效後,proxy_pass url 連接中的路徑會被忽略,如:ide
server { listen 83; location / { rewrite ^/api/(.*) /fixpath=$1 break; proxy_pass http://127.0.0.1:3000/node/; } location ^/api/ { rewrite ^/api/(.*) /fixpath=$1 break; proxy_pass http://127.0.0.1:3000/node/; } }
訪問 http://127.0.0.1:83/bb/cc
獲得 您的 請求 地址是/node/bb/cc
(匹配上 / 了,沒有匹配 rewrite)
訪問 http://127.0.0.1:83/api/cc
獲得 您的 請求 地址是/fixpath=cc
(咱們寫的 proxy_pass http://127.0.0.1:3000/node/
裏面的 node
路徑丟失了 )post
知道了這幾點,碰到轉發接口也有一點底氣啦~
在github上看到的這本小書 ⬇️
(參考資料)[https://xuexb.github.io/learn...]
個人 nginx
配置
events { } http { # proxy_pass url 只是 host # 這時候 location 匹配的完整路徑將直接透傳給 url ,如: server { listen 80; location / { proxy_pass http://127.0.0.1:3000; } location /api/ { proxy_pass http://127.0.0.1:3000; } } # url 包含路徑 # 當 proxy_pass url 的 url 包含路徑時,匹配時會根據 location 的匹配後的連接透傳給 url ,注意匹配後就是這樣: server { listen 81; location / { proxy_pass http://127.0.0.1:3000/; } location /api/ { proxy_pass http://127.0.0.1:3000/; } location /bpi/ { proxy_pass http://127.0.0.1:3000/v1; } location /cpi { proxy_pass http://127.0.0.1:3000/v1; } } # 當 location 以正則形式匹配時,proxy_pass 就不能以 / 結束了,也就是不能包含路徑了, 會提示配置錯誤,好比錯誤的: server { listen 82; location / { proxy_pass http://127.0.0.1:3000/; } # nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /test.conf:47 # location ~* ^/api/ { # proxy_pass http://127.0.0.1:3000/; # } # nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /Users/tangdaoyuan/code/anheng/jz-bingjiang/test.conf:52 # location ~* ^/api/ { # proxy_pass http://127.0.0.1:3000/b1; # } } # 使用 rewrite 指令而且生效後,proxy_pass url 連接中的路徑會被忽略,如: server { listen 83; location / { proxy_pass http://127.0.0.1:3000/node/; } location ^/api/ { rewrite ^/api/(.*) /fixpath=$1 break; proxy_pass http://127.0.0.1:3000/node/; } } }
測試流程 : node 運行 服務, 啓動Nginx 轉發 , 再用postman 發送請求。