轉載於:http://www.cnblogs.com/zhaof/p/5945576.html?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.iohtml
location 指令的做用是根據用戶請求的URI來執行不一樣的應用,URI就是根據用戶請求到的網址URL進行匹配,匹配成功了進行相關的操做。nginx
下面是官網的語法結構:正則表達式
Syntax: location [ = | ~ | ~* | ^~ ] uri { ... }express
location @name { ... }服務器
Default: —app
Context: server, locationide
下面會結合官網原文進行解釋,如下英文部分均從官網摘抄:網站
http://nginx.org/en/docs/http/ngx_http_core_module.html#locationspa
(翻譯的很差勿噴)翻譯
Sets configuration depending on a request URI.
根據請求的URI進行配置
URI 變量是待匹配的請求字符串,
A location can either be defined by a prefix string, or by a regular expression.
Regular expressions are specified with the preceding 「~*」 modifier (for case-insensitive matching), or the 「~」 modifier (for case-sensitive matching)
一個location能夠用prefix string(前綴字符串)定義,也能夠經過regular expression(正則表達式來定義)
通俗的說也就是:咱們能夠經過使用不一樣的前綴,表達不一樣的含義,對於不一樣的前綴能夠分爲兩大類:普通location和正則location
符號:」~」表示uri包含正則,而且區分大小寫
符號:「~*」表示uri包含正則,但不區分大小寫
注意:若是你的uri用正則,則你的正則前面必須添加~或者~*,以前我在這裏存在誤區,覺得能夠不加~或者~*
To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered. Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.
Nginx服務器會首先會檢查多個location中是否有普通的uri匹配,若是有多個匹配,會先記住匹配度最高的那個。而後再檢查正則匹配,這裏切記正則匹配是有順序的,從上到下依次匹配,一旦匹配成功,則結束檢查,並就會使用這個location塊處理此請求。若是正則匹配所有失敗,就會使用剛纔記錄普通uri匹配度最高的那個location塊處理此請求。
If the longest matching prefix location has the 「^~」 modifier then regular expressions are not checked.
當普通匹配的最長前綴匹配有符號「^~」的時候,就不會在匹配正則
直接使用當前匹配的這個location塊處理此請求
Also, using the 「=」 modifier it is possible to define an exact match of URI and location. If an exact match is found, the search terminates. For example, if a 「/」 request happens frequently, defining 「location = /」 will speed up the processing of these requests, as search terminates right after the first comparison. Such a location cannot obviously contain nested locations.
使用符號「=」修飾符能夠定義一個精確匹配的URI和位置,若是找到了一個精確的匹配,則搜索終止,例如,若是一個」/」請求頻繁發生,定義「location =/」將加快這些請求的處理,一旦精確匹配只有就結束,這樣的location顯然不能包含嵌套location
這裏咱們說一下location / {} 和location =/ {}的區別:
「location / {}」是普通的最大前綴匹配,任何的uri確定是以「/」開頭,因此location / {} 能夠說是默認匹配,當其餘都不匹配了,則匹配默認匹配
a. 」=」用於普通uri前,要求精確匹配,若是匹配成功,則中止搜索並用當前location處理此請求
b. 」~」 表示uri包含正則,而且區分大小寫
c. 「~*」表示uri包含正則,但不區分大小寫
d. 」^~」表示在普通uri前要求Nginx服務器找到普通uri匹配度最高的那個location後,當即處理此請求,並再也不進行正則匹配
e. 」^~」和「=」均可以阻止繼續匹配正則location二者的區別:「^~」依然遵照最大前綴原則,而後「=」是須要嚴格匹配
這是一個錯誤的結論,從上面官網的文章中咱們能夠知道:
先匹配普通uri,而後記住匹配度最高的那個(官網原話:To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered.)而後匹配正則,若是正則匹配則結束查找,若是正則不匹配,則匹配以前普通匹配中匹配度最高的那個將執行該請求(官網原話:Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.)
因此:location 的匹配順序是「先匹配正則,再匹配普通」 這句話確定是錯誤的,何況這裏並無包含」^~」和「=」
這也是一種錯誤的理解,咱們根據上述內容能夠知道:
若是是普通uri 匹配,這個時候是沒有順序的,可是正則匹配則是有順序的,是從上到下依次匹配,一旦有匹配成功,則中止後面的匹配。
對www.conf配置以下:
[root@nginx extra]# cat www.conf
server {
listen 80;
server_name www.zhaofan.com;
access_log logs/access_www.log;
root html/www;
location / {
return 401;
}
location = / {
return 402;
}
location /documents/ {
return 403;
}
location ^~ /p_w_picpaths/ {
return 404;
}
location ~* \.(gif|jpg|jpeg)$ {
return 500;
}
}
[root@nginx extra]#
注意:
location ~* \.(gif|jpg|jpeg)$ {
return 500;
這個部分$前面不能有空格,不然會提示以下錯誤:
[root@nginx extra]# ../../sbin/nginx -s reload
nginx: [emerg] invalid location modifier "~*\.(gif|jpg|jpeg)" in /application/nginx1.6.2/conf/extra/www.conf:19
若是$後面沒有空格,則會提示以下錯誤:
[root@nginx extra]# ../../sbin/nginx -s reload
nginx: [emerg] directive "location" has no opening "{" in /application/nginx1.6.2/conf/extra/www.conf:23
這些都是細節問題,必定要注意
能夠看出這裏是精確匹配
location = / {
return 402;
}
這裏能夠看出由於都不匹配,因此最後匹配了location / {}
location / {
return 401;
}
這裏能夠看出是匹配了正則
location ~* \.(gif|jpg|jpeg)$ {
return 500;
}
這裏依然是匹配正則
location ~* \.(gif|jpg|jpeg)$ {
return 500;
}
location / {
return 401;
}
location = / {
return 402;
}
location /document/ {
return 403;
}
location ^~ /p_w_picpaths/ {
return 404;
}
location ~* \.(gif|jpg|jpeg)$ {
return 500;
}
這裏經過配置把實驗三和實驗四的對比就能夠看出來由於普通匹配裏有「^~」,而且匹配到了p_w_picpaths,因此這個就是不進行正則匹配
location ^~ /p_w_picpaths/ {
return 404;
}
配置以下:
location / {
return 401;
}
location = / {
return 402;
}
location = /document/ {
return 403;
}
location ^~ /p_w_picpaths/ {
return 404;
}
location /p_w_picpaths/1/ {
return 501;
}
location ~* \.(gif|jpg|jpeg)$ {
return 500;
}
仍是關注標紅的地方,這個時候咱們登錄:http://192.168.1.19/p_w_picpaths/
結果以下:
從這裏能夠看出匹配了:
location ^~ /p_w_picpaths/ {
return 404;
}
可是若是咱們登錄:http://192.168.1.19/p_w_picpaths/1/
結果以下;
這裏匹配了:
location /p_w_picpaths/1/ {
return 501;
}
從這裏咱們能夠看出「^~」遵照最大匹配原則。
配置以下:
location / {
return 401;
}
location = / {
return 402;
}
location = /document/ {
return 403;
}
location ^~ /p_w_picpaths/ {
return 404;
}
location /p_w_picpaths/1/ {
return 501;
}
location = /p_w_picpaths/1/ {
return 502;
}
location ~* \.(gif|jpg|jpeg)$ {
return 500;
}
登錄:http://192.168.1.19/p_w_picpaths/1/
結果以下:
可是若是這個時候登錄:http://192.168.1.19/p_w_picpaths/1/aaa/
結果以下:
從這裏咱們能夠看出當精確匹配和最長匹配相同時,匹配的是精確匹配。
不在過多的作實驗,根據上面的邏輯圖應該能夠解決碰到的問題了