本文介紹有關 User-Agent 的知識,以及使用 Nginx map 指令配合正則表達式匹配 User Agent 自定義值,經過捕獲 UA 自定義值,能夠作不少事情,其中一個場景是:讓一臺測試機支持多個測試同時測試一個項目,原理就是匹配 UA 值,設置不一樣的 WEB 根目錄。php
User Agent 中文名爲用戶代理,簡稱 UA,它是一個特殊字符串頭,使得服務器可以識別客戶使用的操做系統及版本、CPU 類型、瀏覽器及版本、瀏覽器渲染引擎、瀏覽器語言、瀏覽器插件等。html
用 Firefox的 Firebug 工具能夠看到每次請求的請求頭信息都包含 User-Agent 字段,如圖所示:nginx
經過查看 nginx 的請求日誌如 access.log,也能夠查看到每次請求的 UA 信息,若是是 curl 命令方式請求,能夠看到 UA 信息是 curl:正則表達式
192.168.10.1 – – [10/Oct/2016:02:42:59 +0000] 「GET /hello HTTP/1.1」 200 18 「-」 「Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 tanteng」
127.0.0.1 – – [10/Oct/2016:02:43:23 +0000] 「GET /hello HTTP/1.1」 200 22 「-」 「curl/7.35.0」瀏覽器
這個插件能夠管理和切換不一樣的 User-Agent,好比模擬不一樣的瀏覽器,或者新增自定義的 UA,能夠在 UA 中帶上本身的標識。bash
好比新增一個本身的 UA,並加上本身的標識,如圖:服務器
這樣 Firefox 發出的請求頭信息中 UA 就是這個修改事後的,訪問一個本地 WEB 項目,經過 firebug 或查看 nginx 的 access.log 日誌,均可以發現請求 UA 發生了變化。curl
在 nginx 配置文件中,$http_user_agent 表示 UA 的值,好比瀏覽器默認 UA 值是:工具
Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0性能
如今新增了一個 UA,UA 值是在後面加一個空格和名字,如:
Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 tanteng
經過 Firefox 的 User Agent Swicher 這個插件切換到新的 UA,再經過瀏覽器訪問,UA 就是這個修改以後的。
那麼,在 nginx 中如何匹配這個最後的名字呢?這裏能夠用到 nginx 的 map 指令配合正則表達式。
map 指令使用 ngx_http_map_module 模塊提供的,ngx_http_map_module 模塊能夠建立變量,這些變量的值與另外的變量值相關聯。容許分類或者同時映射多個值到多個不一樣值並儲存到一個變量中,map 指令用來建立變量,可是僅在變量被接受的時候執行視圖映射操做,對於處理沒有引用變量的請求時,這個模塊並無性能上的缺失。
在 nginx 的 http 域中,增長如下代碼:
map $http_user_agent $user { default ''; ~curl curl; ~(?<name>[\S]+$) $name; }
這裏正則表達式 [\S]+$ 即匹配最後一個非空白字符,?<name> 表示要匹配的結果用 $name 表示。
這個 map 域的意思是,匹配對象是 $http_user_agent,即 UA,默認 $user 值是空字符串,若是是 curl 開頭的,$user 值就是 curl,若是能夠匹配到最後一個非空字符串,那麼 $user 的值就是這個最後的字符串。
在 server 域中添加以下測試代碼:
location /hello { echo http_user_agent:$http_user_agent; echo user:$user; }
執行 curl 命令:curl www.tanteng.me/hello
返回結果:
http_user_agent:curl/7.35.0
user:curl
在瀏覽器中訪問,輸出結果是:
http_user_agent:Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 tanteng
user:tanteng
這樣就成功獲取到 UA 後面增長的一個值。
經過 map 指令獲取到 UA 自定義值後,能夠作以下設置,讓不一樣的測試人員對應不一樣的網站根目錄:
location ~ \.php$ { try_files $uri =404; root /usr/share/nginx/html/$user/public; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
這裏 root 行,網站目錄能夠用 $user 變量來表示。好比測試人員 ruike,他修改本身的 UA 後面加上 ruike,那麼訪問的網站根目錄是 /usr/share/nginx/html/ruike/public,這樣不一樣的測試人員在本身的各自目錄拉取代碼,互不影響,支持同時進行測試。
測試一下效果,把 public 下的 index.php 文件前面用 echo ‘wo shi ruike.’;exit; 輸出。
切換到 ruike 這個 UA,訪問網站,顯示的便是以上內容,切換回 tanteng 這個 UA,顯示的是正常的網站內容,這就達到了經過 UA 自定義值設置不一樣的網站根目錄的效果,也就支持了一臺測試機支持不一樣的測試人員同時進行測試的需求。