使用以下 nginx 位置指令
location ~* (.*)(\/graphql)$ {
proxy_pass http://my-backend:80/$2;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
我希望像這樣的 URLhttps://example.com/anything/graphql被重定向到,http://my-backend:80/$2但事實并非如此,因為每當我嘗試訪問以/graphql. 錯誤將是
[error] 31#31: *1 no resolver defined to resolve my-backend, client: 172.18.0.1, server: localhost, request: "GET /anything/graphql HTTP/2.0", host: "localhost"
uj5u.com熱心網友回復:
這是一個已知的 nginx 限制,您不能proxy_pass在正則運算式位置內指定 URI。如果您嘗試做類似的事情
proxy_pass http://my-backend/graphql;
你有以下 nginx 錯誤:
nginx:[emerg]“proxy_pass”不能在正則運算式給出的位置,或在命名位置內,或在“if”陳述句內,或在...中的“limit_except”塊內有URI部分
相反,您有兩個選擇。第一個是使用變數將您想要的任何內容作為 URI 傳遞給上游,無論是您選擇的方式,或者,如果它是一個常量字串,則明確指定您的端點,如
set $endpoint graphql;
proxy_pass http://my_backend/$endpoint;
但是,這種方法有一個您已經面臨的缺點 -resolver如果您的上游是通過主機名而不是 IP 地址指定的,則需要定義。那就是
proxy_pass http://localhost/$endpoint;
配置行需要一個決議器,而
proxy_pass http://127.0.0.1/$endpoint;
不需要它。$endpoint變數僅用于 URI 部分并不重要。如果您想知道這有什么需要,讓我參考已經提到resolver的博客文章中最相關的部分:
Linux、POSIX 等僅提供一種從名稱獲取 IP 的方法:
gethostbyname. 如果您花時間閱讀手冊頁(這樣做總是安全的... ;))您會意識到決議名稱需要做很多事情:打開檔案,詢問 NIS 或 YP 他們對此有何看法,詢問 DNS 服務器(可能有幾種不同的方式)。而這一切都是同步的。現在你已經習慣了 nginx 的方式,你知道這有多糟糕,你不想走丑陋的同步方式。因此,忠于自己的 Igor 重新實作了 DNS 查找(請注意,使用記憶體快取)只是為了避免呼叫這種丑陋的阻塞gethostbyname......這就是我們有這個額外resolver指令的原因。是的,撰寫最快的網路服務器是有代價的……
當沒有其他方法只能將變數與. 一起使用時proxy_pass,可以選擇使用公共 DNS 8.8.8.8,但是設定您自己的本地 DNS 應該性能更高(或者您將與該8.8.8.8主機進行持續的流量交換)。然而,還有另一種選擇。您可以將 location 塊內的 URI 重寫為所需的,并在proxy_pass不使用任何其他變數的情況下使用:
location ~ /graphql$ {
rewrite ^ /graphql break;
proxy_pass http://my-backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
在大多數情況下,這是一種更方便的方式,因為使用這樣的配置您根本不需要任何指定resolver。
如您所見,我在這里不使用任何捕獲組,因為使用它們來解決您的特定情況沒有任何實際意義。給定的正則運算式與您的完全相同(同時性能稍高一些)。但是,在某些情況下您確實需要使用它們,并且如果確實需要使用捕獲組的人會閱讀此內容,則必須警告他這樣做的直接方法是
location ~ (/graphql)$ {
rewrite ^ $1 break;
...
不會作業。原因是每當正則運算式模式匹配操作發生時,都會重新評估編號的捕獲,并且該rewrite指令正是執行此類操作的指令之一(使其$1成為空字串)。解決方案是改用命名捕獲組:
location ~ (?<url>/graphql)$ {
rewrite ^ $url break;
...
或者可以重用正則運算式模式(我認為這會降低性能):
location ~ /graphql$ {
rewrite (/graphql)$ $1 break;
...
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/476738.html
標籤:正则表达式 nginx nginx-反向代理 http-重定向
下一篇:入口資源檔案錯誤AKS-spec.rules[0].http.paths[0].pathType:必需值:必須指定pathType
