Nginx配置:讀取自定義header + 撰寫AND條件 + 修改響應體 + 域名重定向

需求

不修改代碼的情況下,在nginx轉發請求時修改response body獲取期望值。

請求有2個特徵唯一定位:

  1. url:/aaa/bbb/ccc/ddd
  2. 自定義header(區分版本):System-Version: pro 不同版本會請求相同服務器下相同url

Tip:這麼幹的原因主要是由於上線管控,問題修復後不能隨時上線。但是線上部分用戶已經不能正常使用功能了,所以算是一個暫時解決方案,不提倡不鼓勵這麼幹哇~

原返回值:

{
  "code": 200,
  "data": {
    "deployAdmin": false,
    "systemId": "aaa"
  }
}

期望返回值:

// deployAdmin控制頁面顯示,這裏期望爲true
{
  "code": 200,
  "data": {
    "deployAdmin": true,
    "systemId": "aaa"
  }
}

實現

基於基本nginx配置,不需安裝額外模塊(安裝額外模塊得找運維,也趕不及-_-)。

讀取自定義header

首先,開啓underscores_in_headers

解釋:HTTP頭部是否允許下劃線。默認爲off,表示HTTP頭部的名稱中不允許帶“_”
語法:underscores_in_headers on | off;
默認:underscores_in_headers off;
配置塊:http、server

然後,通過$http_加自定義header讀取目標請求頭(純小寫,中劃線替換爲下劃線)
比如:獲取 System-Version 應寫爲 $http_system_version

# nginx.conf
server {
    listen          80;
    ...
    underscores_in_headers on;  
    ...
    location ~ ^/aaa/ {
        ... 
        if ($http_system_version = "pro") {
            ...
        }
    }
}

撰寫AND條件

nginx配置中使用 if(a && b) 的條件判斷是無效的。但需求中要求的條件是 url = '/aaa/bbb/ccc/ddd' 並且 $http_system_version = 'pro' 。解決思路是聲明一個變量,每判斷一個條件爲true,就將變量修改一下,最後直接判斷該變量是否達到了所有條件爲true的修改狀態即可。

# nginx.conf

location ~ ^/aaa/ {
    ...
    
    set $a 0;
    if ($http_system_version = "pro"){
        set $a 1;
    }
    if ($request_uri ~ ^/aaa/bbb/ccc/ddd) {
        set $a 1$a;
    }
    if ($a = '11') {
        ... 
    }
}

修改響應體

直接上這段邏輯完整配置

location ~ ^/aaa/ {
    # 以/aaa開頭的請求代理到 http://xxx.yyy.com
    proxy_pass http://xxx.yyy.com;
    proxy_redirect          off; 
    proxy_set_header        X-Real-IP       $remote_addr; 
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    
    # AND條件判斷變量
    set $a 0;
    # 請求中自定義header頭System-Version爲"pro"
    if ($http_system_version = "pro") {
        set $a 1;
    }
    # 請求url爲'/aaa/bbb/ccc/ddd'
    if ($request_uri ~ ^/aaa/bbb/ccc/ddd) {
        set $a 1$a;
    }
    # 兩個條件都符合時return 期望返回值
    if ($a = '11') {
        return 200 '{"code":200,"data":{"deployAdmin":true,"systemId":"aaa"}}';
    }
}

Tip: if後一定要跟空格,不然nginx會報錯~

域名重定向

小記一下,跟本次需求無關聯

服務器對應兩個域名123.yy.com456.yy.com,用戶訪問123.yy.com時,將請求重定向到456.yy.com(此時瀏覽器地址欄url域名會被替換)。這種情況適用與新老域名過渡期~

if ($host = '123.yy.com') {
    rewrite ^/(.*)$ http://456.yy.com/$1 permanent;
}

小記

有一個過濾器模塊 ngx_http_sub_module,它可以通過將一個指定的字符串替換爲另一個字符串來響應,但需要安裝,默認不帶。

另:更靈活的配置可通過搭配lua

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章