Location指令是nginx中最關鍵的指令之一,location指令的功能是用來匹配不一樣的url請求,進而對請求作不一樣的處理和響應,這其中較難理解的是多個location的匹配順序,本文會做爲重點來解釋和說明。javascript
開始以前先明確一些約定,咱們輸入的網址叫作請求URI,nginx用請求URI與location中配置的URI作匹配。php
首先咱們先簡單瞭解Nginx的文件結構,Nginx的HTTP配置主要包括三個區塊,結構以下:css
Global: nginx 運行相關 Events: 與用戶的網絡鏈接相關 http http Global: 代理,緩存,日誌,以及第三方模塊的配置 server server Global: 虛擬主機相關 location: 地址定向,數據緩存,應答控制,以及第三方模塊的配置
從上面展現的nginx結構中能夠看出location屬於請求級別配置,這也是咱們最經常使用的配置。html
⚠️ 全部的全部的全部的指令,都要以 ; 結尾
Location 塊經過指定模式來與客戶端請求的URI相匹配。
Location基本語法:前端
location [ = | ~ | ~* | ^~ ] /uri/ { … } location @/name/ { … }
參數 | 解釋 |
---|---|
空 | location後沒有參數直接跟着URI,表示前綴匹配,表明跟請求中的URI從頭開始匹配。 |
= | 用於標準 uri 前,要求請求字符串與其嚴格匹配,成功則當即處理,nginx中止搜索其餘匹配。 |
^~ | 用於標準 uri 前,並要求一旦匹配到就會當即處理,再也不去匹配其餘的那些個正則 uri,通常用來匹配目錄 |
~ | 用於正則 uri 前,表示 uri 包含正則表達式, 區分大小寫 |
~* | # 用於正則 uri 前, 表示 uri 包含正則表達式, 不區分大小寫 |
@ | 」@「 定義一個命名的 location,@定義的locaiton名字通常用在內部定向,例如error_page, try_files命令中。它的功能相似於編程中的goto。 |
Nginx有兩層指令來匹配請求URI。第一個層次是server指令,它經過域名、ip和端口來作第一層級匹配,當找到匹配的server後就進入此server的location匹配。location的匹配並不徹底按照它們在配置文件中出現的順序來匹配,請求URI會按以下規則跟server裏配置的location匹配。java
簡單來講按這個規則 location 匹配命令的優先級從高到低依次爲(序號越小優先級越高):nginx
1. location = /a {…} #精準匹配 2. location ^~ /a {…} #前綴匹配 3. location ~ /a.* {…} #正則匹配(區分大小寫) 4. location ~* /a.* {…} #正則匹配(不區分大小寫) 5. location /a {…} #最長前綴匹配,可是優先級低於正則匹配。 /a 和 ^~ /a 會衝突,報錯 6. location / {} #任何沒有匹配成功的,都會匹配這裏處理
讓咱們用一個例子來講明上面的內容:web
# 請求: # / # /index.html # /documents/document.html # /images/1.gif # /documents/1.jpg location = / { # 只匹配 / 的查詢. [ configuration A ] } # 能匹配成功: / location / { # 匹配任何請求,由於全部請求都是以」/"開始 # 可是更長字符匹配或者正則表達式匹配會優先匹配 [ configuration B ] } #能匹配成功:/index.html location /documents/ { # 匹配任何以 /documents/ 開頭的地址,匹配符合之後,還要繼續往下搜索/ # 只有後面的正則表達式沒有匹配到時,這一條纔會採用這一條/ [ configuration C ] } # 能匹配成功:/documents/document.html location ~ /documents/ABC { # 匹配任何以 /documents/ 開頭的地址,匹配符合之後,還要繼續往下搜索/ # 只有後面的正則表達式沒有匹配到時,這一條纔會採用這一條/ [ configuration CC ] } location ^~ /images/ { # 匹配任何以 /images/ 開頭的地址,匹配符合之後,中止往下搜索正則,採用這一條。/ [ configuration D ] } # 能成功匹配:/images/1.gif location ~* \.(gif|jpg|jpeg)$ { # 匹配全部以 .gif、.jpg 或 .jpeg 結尾的請求,不區分大小寫 # 然而,全部請求 /images/ 下的圖片會被 [ config D ] 處理,由於 ^~ 到達不了這一條正則/ [ configuration E ] } # 能成功匹配:/documents/1.jpg location /images/ { # 字符匹配到 /images/,繼續往下,會發現 ^~ 存在/ [ configuration F ] } location /images/abc { # 最長字符匹配到 /images/abc,繼續往下,會發現 ^~ 存在/ # F與G的放置順序是沒有關係的/ [ configuration G ] } location ~ /images/abc/ { # 只有去掉 [ config D ] 纔有效:先最長匹配 [ config G ] 開頭的地址,繼續往下搜索,匹配到這一條正則,採用/ [ configuration H ] } location ~* /js/.*/\.js
請求URI中問號後面的參數是不能在location中匹配到的,這些參數存儲在$query_string變量中,能夠用if來判斷。
例如,對於參數中帶有單引號’進行匹配而後重定向到錯誤頁面。面試
/plus/list.php?tid=19&mid=1124’ if ( $query_string ~* 「.*[;’<>].*」 ){ return 404; }
這個不少解釋不太準確,我有必要多說幾句。
對於請求URI結尾是否帶有/,通常的處理邏輯是帶/表示訪問目錄,不帶/表示訪問文件,若是文件不存在也會去匹配目錄。例如訪問http://www.nginx.cn/images/和...://www.nginx.cn/images,前面的請求會匹配目錄,後面的請求會先匹配文件,文件不存再匹配目錄
對於locatioin中的URI來講,若是URI的結尾帶有/,而且location要執行的命令式是proxy_pass、fastcgi_pass、uwsgi_pass、scgi_pass、memcached_pass、grpc_pass之一。例如:正則表達式
location /images/ { proxy_pass http://www.redis.com.cn }
對於這種狀況,nginx會作特殊處理,無論images命名的文件或目錄存在不在,若是你訪問http://www.nginx.cn/images會...://www.nginx.cn/images/。
因此若是你想這兩種請求對應不一樣的處理,就要明確增長不帶/結尾的location配置。
location /images { proxy_pass http://www.rabbitmq.cn } location /images/ { proxy_pass http://www.redis.com.cn }
帶有」@「的location是用來定義一個命名的location,這種location不參與請求匹配,通常用在內部定向。例如用在error_page, try_files命令中。它的功能相似於編程中的goto。
location /images { try_files $uri $uri/ @name; } location @name { … }
因此實際使用中,我的以爲至少有三個匹配規則定義,以下:
直接匹配網站根,經過域名訪問網站首頁比較頻繁,使用這個會加速處理,官網如是說。
這裏是直接轉發給後端應用服務器了,也能夠是一個靜態首頁。第一個必選規則:
location = / { proxy_pass http://tomcat:8080/index }
第二個必選規則是處理靜態文件請求,這是nginx做爲http服務器的強項,有兩種配置模式,目錄匹配或後綴匹配,任選其一或搭配使用:
location ^~ /static/ { root /webroot/static/; } location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ { root /webroot/res/; }
第三個規則就是通用規則,用來轉發動態請求到後端應用服務器,非靜態文件請求就默認是動態請求,本身根據實際把握,畢竟目前的一些框架的流行,帶.php,.jsp後綴的狀況不多了:
location / { proxy_pass http://tomcat:8080/ }
本文參考/引用:
Module ngx_http_core_module - nginx.org
nginx 中文文檔 - nginx location匹配規則 - nginx.cn
nginx 一文完全讀懂nginx中的location指令 - nginx.cn
nginx 這一篇就夠了 - 哆啦A夢的猜測 - 掘金
nginx 配置location總結及rewrite規則寫法 - seanlook - 思否
nginx平臺初探(100%) — Nginx開發從入門到精通
推薦閱讀:
【專題:JavaScript進階之路】
JavaScript中各類源碼實現(前端面試筆試必備)
深刻理解 ES6 Promise
前端性能優化小結(面試乾貨)
ES6 尾調用和尾遞歸
我是Cloudy,現居上海,年輕的前端攻城獅一枚,愛專研,愛技術,愛分享。
我的筆記,整理不易,感謝關注
、閱讀
、點贊
和收藏
。
文章有任何問題歡迎你們指出,也歡迎你們一塊兒交流各類前端問題!