在實現微信小程序內嵌非業務域名時,通過nginx做鏡像網站繞過小程序業務域名檢測,但有一些表單頁面提交后會返回一個302狀態,由響應頭Location的值決定提交成功后的跳轉地址。那么問題來了,這個地址也是屬於非業務域名,這個時候我們就需要將這個響應頭也替換掉,那么nginx如何替換響應頭呢,請看下面教程:
一、安裝使用ngx_headers_more模塊定制響應頭:
ngx_headers_more 用於添加、設置和清除輸入和輸出的頭信息。nginx沒有內置該模塊,需要另行添加。
(1)下載地址:https://github.com/openresty/headers-more-nginx-module/tags
(2)平滑升級nginx(參考上篇為nginx平滑添加SSL模塊的文章:http://www.cnblogs.com/kenwar/p/8295907.html 添加參數add-module=/解壓縮后文件路徑)
(3)指令說明(我這邊只用到設置響應頭的指令,所以只介紹一個指令,如有興趣請自行查找其使用說明):
more_set_headers
語法:more_set_headers [-t <content-type list>]... [-s <status-code list>]... <new-header>...
默認值:no
配置段:http, server, location, location if
階段:輸出報頭過濾器
替換(如有)或增加(如果不是所有)指定的輸出頭時響應狀態代碼與-s選項相匹配和響應的內容類型的-t選項指定的類型相匹配的。
如果沒有指定-s或-t,或有一個空表值,無需匹配。因此,對於下面的指定,任何狀態碼和任何內容類型都講設置。
more_set_headers "Server: my_server"; more_set_headers "Server: my_server";
具有相同名稱的響應頭總是覆蓋。如果要添加頭,可以使用標准的add_header指令代替。
單個指令可以設置/添加多個輸出頭。如:
more_set_headers 'Foo: bar' 'Baz: bah'; more_set_headers 'Foo: bar' 'Baz: bah';
在單一指令中,選項可以多次出現,如:
more_set_headers -s 404 -s '500 503' 'Foo: bar'; more_set_headers -s 404 -s '500 503' 'Foo: bar';
等同於:
more_set_headers -s '404 500 503' 'Foo: bar'; more_set_headers -s '404 500 503' 'Foo: bar';
新的頭是下面形式之一:
Name: Value
Name:
Name
最后兩個有效清除的頭名稱的值。Nginx的變量允許是頭值,如:
set $my_var "dog"; more_set_headers "Server: $my_var"; set $my_var "dog"; more_set_headers "Server: $my_var";
注意:more_set_headers允許在location的if塊中,但不允許在server的if塊中。下面的配置就報語法錯誤:
# This is NOT allowed! server { if ($args ~ 'download') { more_set_headers 'Foo: Bar'; } ... }
二、簡單替換302狀態下的響應頭Location:
location /{ more_set_header "Location" "https://www.demo.com/xxx/index.html" }
三、(重點)使用正則表達式有選擇的替換Location:
我們如果需要根據響應頭里的內容來選擇何種替換方式,該怎么做?
需求:在location中判斷響應頭Location字段如果值為a(假設值),則將Location設置為b,其他忽略
(1)初步嘗試:
location /{ if($upstream_http_Location ~ a){ more_set_header "Location" "https://www.demo.com/xxx/index.html" } }
然而這里的if怎么都進不去,通過google得知是因為,在請求傳遞到后端之前,if就已經判斷了,所以$upstream_http_Location是沒有值的,這里可以使用一個map來有根據響應頭的值有條件的執行操作:
map $upstream_http_Location $location{ ~a https://www.democom/xxx/success.html; default $upstream_http_Location; } server{ listen 80; listen 443 ssl; ssl_certificate /usr/local/nginx/ssl/www3.xiaolintong.net.cn/www3.xiaolintong.net.cn-ca-bundle.crt; ssl_certificate_key /usr/local/nginx/ssl/www3.xiaolintong.net.cn/www3.xiaolintong.net.cn.key; autoindex on; #開啟讀取非nginx標准的用戶自定義header(開啟header的下划線支持) underscores_in_headers on; server_name xxxxxxxxx; access_log /usr/local/nginx/logs/access.log combined; index index.html index.htm index.jsp index.php; #error_page 404 /404.html; ........ location ^~/f/ { more_set_headers -s '302' 'Location $location'; } ....... }
這里僅提供一個思路,請根據自己的需求靈活的使用map