Nginx
$sent_http_ 變數在某些情況下會在 Nginx 中消失
我在 Nginx 上遇到了一個奇怪的問題。這是重現錯誤的最小配置:
server { server_name mydomain.com; listen 111.111.111.111:80; root /some/path; set $some_var $sent_http_content_type; add_header "X-Debug" $sent_http_content_type; }
在這種情況下
X-Debug
,響應中永遠不會顯示標頭。但是,如果我評論這一行:set $some_var $sent_http_content_type;
一切正常。這對我來說似乎很奇怪,因為這一行不會重新分配
$sent_http_content_type
var,而只會讀取。看起來它只屬於
$sent_http_
變數。我也嘗試過
"${sent_http_content_type}"
,而不是$sent_http_content_type
相同的結果。
more_set_headers
指令沒有解決這個問題。為什麼 Nginx 會有這樣的行為?這是一個錯誤嗎?
編輯:
我提供的範例只是$sent_http_
vars 消失的最簡單情況。事實上,我想做這樣的事情:if ($sent_http_access_control_allow_origin ~ "^(https?)://([^/]+)") { set $new_cors http://$1.$2.proxy.mydomain.com; } more_set_headers "Access-Control-Allow-Origin: $new_cors";
我編寫了一個代理伺服器,我需要替換
Access-Control-Allow-Origin
響應標頭,因為否則代理站點無法按預期工作。在上面的範例
if
條件(server
部分)中true
,即使有這樣的標題並且它符合我的正則表達式,它也永遠不會產生。這可以解決嗎?感謝你的幫助!
Nginx 的
rewrite
模組(變數和set
指令所屬的地方)非常不直覺且脆弱。但實際上set $some_var $sent_http_content_type;
無論如何都是沒有意義的,因為
set
指令是在請求開始時執行的,目前沒有$sent_http_*
可用的變數。您可以做的(如果您真的想以
$sent_http_*
某種方式使用變數)是使用map
指令。map $sent_http_content_type $some_var { default $sent_http_content_type; } ... server { ... add_header "X-Debug" $sent_http_content_type; add_header "X-Debug2" $some_var; }
編輯:你的問題可以用更多
map
的 s 來解決,但如果你可以使用 Lua 模組會容易得多。在這裡如何用
map
s 完成它:(非常不可讀和不可維護)map $sent_http_access_control_allow_origin $__proto { default "NONE"; "~^(?<_>https?):" "$_"; } map $sent_http_access_control_allow_origin $__host { default ""; "~^https?://(?<_>[^/]+)" "$_"; } map "http://$__proto.$__host.proxy.mydomain.com" $new_cors { default ""; "~^http://NONE" ""; "~^(?<_>.+)$" "$_"; }