第三講 nginx的location模塊

本章主要內(nèi)容是nginx的location模塊晨抡,也是最重要的模塊。

location模塊:

  • proxy_set_header
    nginx是通過proxy_set_header來設(shè)置請(qǐng)求頭迷守,它的語法如下:
    proxy_set_header field value;
    默認(rèn)值:
proxy_set_header Host $proxy_host;
proxy_set_header Connection close;

其他一些有用的值:

 proxy_set_header X-Real-IP $remote_addr;#配置這個(gè)之后可以通過 request.getAttribute("X-real-ip"),來獲客戶端取真實(shí)的ip
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
官方文檔解釋

REFER: http://wiki.nginx.org/NginxHttpCoreModule#location
location
syntax:location [=|||^~|@] /uri/ { … }
default:no
context:server
This directive allows different configurations depending on the URI.

(譯者注:1 、different configurations depending on the URI 說的就是語法格式:location [=|||^~|@] /uri/ { … } ,依據(jù)不同的前綴“= ”梨树,“^~ ”,“~ ”岖寞,“~ ”和不帶任何前綴的(因?yàn)閇A] 表示可選抡四,可以不要的),表達(dá)不同的含義, 簡(jiǎn)單的說盡管location 的/uri/ 配置一樣仗谆,但前綴不一樣床嫌,表達(dá)的是不同的指令含義跨释。2 胸私、查詢字符串不在URI范圍內(nèi)厌处。例如:/films.htm?fid=123 的URI 是/films.htm 。)

It can be configured using both literal strings and regular expressions. To use regular expressions, you must use a prefix:

  1. “~” for case sensitive matching
  2. “~*” for case insensitive matching

譯文:上文講到location /uri/ 可通過使用不同的前綴岁疼,表達(dá)不同的含義阔涉。對(duì)這些不同前綴,分下類捷绒,就2 大類:正則location 瑰排,英文說法是location using regular expressions 和普通location ,英文說法是location using literal strings 暖侨。那么其中“~ ”和“~* ”前綴表示正則location 椭住,“~ ”區(qū)分大小寫,“~* ”不區(qū)分大小寫字逗;其他前綴(包括:“=”京郑,“^~ ”和“@ ”)和無任何前綴的都屬于普通location 。

To determine which location directive matches a particular query, the literal strings are checked first.

譯文:對(duì)于一個(gè)特定的 HTTP 請(qǐng)求( a particular query )葫掉, nginx 應(yīng)該匹配哪個(gè) location 塊的指令呢(注意:我們?cè)?nginx.conf 配置文件里面一般會(huì)定義多個(gè) location 的)些举?匹配 規(guī)則是:先匹配普通location (再匹配正則表達(dá)式)。注意:官方文檔這句話就明確說了俭厚,先普通location 户魏,而不是有些同學(xué)的誤區(qū)“先匹配正則location ”。

Literal strings match the beginning portion of the query – the most specific match will be used.

前面說了“普通location ”與“正則location ”之間的匹配規(guī)則是:先匹配普通location 挪挤,再匹配正則location 叼丑。那么,“普通location ”內(nèi)部(普通location 與普通location )是如何匹配的呢?簡(jiǎn)單的說:最大前綴匹配。原文:1睛廊、match the beginning portion of the query (說的是匹配URI 的前綴部分beginning portion )匾乓; 2 、the most specific match will be used (因?yàn)閘ocation 不是“嚴(yán)格匹配”捏顺,而是“前綴匹配”,就會(huì)產(chǎn)生一個(gè)HTTP 請(qǐng)求,可以“前綴匹配”到多個(gè)普通location 贞铣,例如:location /prefix/mid/ {} 和location /prefix/ {} ,對(duì)于HTTP 請(qǐng)求/prefix/mid/t.html 沮明,前綴匹配的話兩個(gè)location 都滿足辕坝,選哪個(gè)?原則是:the most specific match 荐健,于是選的是location /prefix/mid/ {} )酱畅。

Afterwards, regular expressions are checked in the order defined in the configuration file. The first regular expression to match the query will stop the search.

這段話說了兩層意思琳袄,第一層是:“Afterwards, regular expressions are checked ”, 意思是普通location 先匹配,而且選擇了最大前綴匹配后纺酸,不能就停止后面的匹配窖逗,最大前綴匹配只是一個(gè)臨時(shí)的結(jié)果,nginx 還需要繼續(xù)檢查正則location (但至于最終才能普通location 的最大前綴匹配餐蔬,還是正則location 的匹配碎紊,截止當(dāng)前的內(nèi)容還沒講,但后面會(huì)講)樊诺。第二層是“regular expressions are checked in the order defined in the configuration file. The first regular expression to match the query will stop the search. ”仗考,意思是說“正則location ”與“正則location”內(nèi)部的匹配規(guī)則是:按照正則location 在配置文件中的物理順序(編輯順序)匹配的(這句話就說明location 并不是一定跟順序無關(guān),只是普通location 與順序無關(guān)词爬,正則location 還是與順序有關(guān)的)秃嗜,并且只要匹配到一條正則location ,就不再考慮后面的(這與“普通location ”與“正則location ”之間的規(guī)則不一樣顿膨,“普通location ”與“正則location ”之間的規(guī)則是:選擇出“普通location ”的最大前綴匹配結(jié)果后锅锨,還需要繼續(xù)搜索正則location )。

If no regular expression matches are found, the result from the literal string search is used.

這句話回答了“普通location ”的最大前綴匹配結(jié)果與繼續(xù)搜索的“正則location ”匹配結(jié)果的決策關(guān)系虽惭。如果繼續(xù)搜索的“正則location ”也有匹配上的橡类,那么“正則location ”覆蓋 “普通location ”的最大前綴匹配(因?yàn)橛羞@個(gè)覆蓋關(guān)系,所以造成有些同學(xué)以為正則location 先于普通location 執(zhí)行的錯(cuò)誤理解)芽唇;但是如果“正則location ”沒有能匹配上顾画,那么就用“普通location ”的最大前綴匹配結(jié)果。

For case insensitive operating systems, like Mac OS X or Windows with Cygwin, literal string matching is done in a case insensitive way (0.7.7). However, comparison is limited to single-byte locale’s only.

Regular expression may contain captures (0.7.40), which can then be used in other directives.

It is possible to disable regular expression checks after literal string matching by using “^~” prefix.If the most specific match literal location has this prefix: regular expressions aren’t checked.

通常的規(guī)則是匆笤,匹配完了“普通location ”指令研侣,還需要繼續(xù)匹配“正則location ”,但是你也可以告訴Nginx :匹配到了“普通location ”后炮捧,不再需要繼續(xù)匹配“正則location ”了庶诡,要做到這一點(diǎn)只要在“普通location ”前面加上“^~ ”符號(hào)(^ 表示“非”,~ 表示“正則”咆课,字符意思是:不要繼續(xù)匹配正則)末誓。

By using the “=” prefix we define the exact match between request URI and location. When matched search stops immediately. E.g., if the request “/” occurs frequently, using “l(fā)ocation = /” will speed up processing of this request a bit as search will stop after first comparison.

除了上文的“^~ ”可以阻止繼續(xù)搜索正則location 外,你還可以加“= ”书蚪。那么如果“^~ ”和“= ”都能阻止繼續(xù)搜索正則location 的話喇澡,那它們之間有什么區(qū)別呢?區(qū)別很簡(jiǎn)單殊校,共同點(diǎn)是它們都能阻止繼續(xù)搜索正則location 晴玖,不同點(diǎn)是“^~ ”依然遵守“最大前綴”匹配規(guī)則,然而“= ”不是“最大前綴”,而是必須是嚴(yán)格匹配(exact match )呕屎。

這里順便講下“l(fā)ocation / {} ”和“l(fā)ocation = / {} ”的區(qū)別让簿,“l(fā)ocation / {} ”遵守普通location 的最大前綴匹配,由于任何URI 都必然以“/ ”根開頭秀睛,所以對(duì)于一個(gè)URI 尔当,如果有更specific 的匹配,那自然是選這個(gè)更specific 的琅催,如果沒有居凶,“/ ”一定能為這個(gè)URI 墊背(至少能匹配到“/ ”),也就是說“l(fā)ocation / {} ”有點(diǎn)默認(rèn)配置的味道藤抡,其他更specific的配置能覆蓋overwrite 這個(gè)默認(rèn)配置(這也是為什么我們總能看到location / {} 這個(gè)配置的一個(gè)很重要的原因)。而“l(fā)ocation = / {} ”遵守的是“嚴(yán)格精確匹配exact match ”抹估,也就是只能匹配 http://host:port/ 請(qǐng)求缠黍,同時(shí)會(huì)禁止繼續(xù)搜索正則location 。因此如果我們只想對(duì)“GET / ”請(qǐng)求配置作用指令药蜻,那么我們可以選“l(fā)ocation = / {} ”這樣能減少正則location 的搜索瓷式,因此效率比“l(fā)ocation / {}” 高(注:前提是我們的目的僅僅只想對(duì)“GET / ”起作用)。

On exact match with literal location without “=” or “^~” prefixes search is also immediately terminated.

前面我們說了语泽,普通location 匹配完后贸典,還會(huì)繼續(xù)匹配正則location ;但是nginx 允許你阻止這種行為踱卵,方法很簡(jiǎn)單廊驼,只需要在普通location 前加“^~ ”或“= ”。但其實(shí)還有一種“隱含”的方式來阻止正則location 的搜索惋砂,這種隱含的方式就是:當(dāng)“最大前綴”匹配恰好就是一個(gè)“嚴(yán)格精確(exact match )”匹配妒挎,照樣會(huì)停止后面的搜索。原文字面意思是:只要遇到“精確匹配exact match ”西饵,即使普通location 沒有帶“= ”或“^~ ”前綴酝掩,也一樣會(huì)終止后面的匹配。

先舉例解釋下眷柔,后面例題會(huì)用實(shí)踐告訴大家期虾。假設(shè)當(dāng)前配置是:location /exact/match/test.html { 配置指令塊1},location /prefix/ { 配置指令塊2} 和 location ~ .html$ { 配置指令塊3} 驯嘱,如果我們請(qǐng)求 GET /prefix/index.html 镶苞,則會(huì)被匹配到指令塊3 ,因?yàn)槠胀╨ocation /prefix/ 依據(jù)最大匹配原則能匹配當(dāng)前請(qǐng)求宙拉,但是會(huì)被后面的正則location 覆蓋宾尚;當(dāng)請(qǐng)求GET /exact/match/test.html ,會(huì)匹配到指令塊1 ,因?yàn)檫@個(gè)是普通location 的exact match 煌贴,會(huì)禁止繼續(xù)搜索正則location 御板。

To summarize, the order in which directives are checked is as follows:

  1. Directives with the “=” prefix that match the query exactly. If found, searching stops.
  2. All remaining directives with conventional strings. If this match used the “^~” prefix, searching stops.
  3. Regular expressions, in the order they are defined in the configuration file.
  4. If #3 yielded a match, that result is used. Otherwise, the match from #2 is used.

這個(gè)順序沒必要再過多解釋了。但我想用自己的話概括下上面的意思“正則 location 匹配讓步普通location 的嚴(yán)格精確匹配結(jié)果牛郑;但覆蓋普通 location 的最大前綴匹配結(jié)果”怠肋。

It is important to know that nginx does the comparison against **decoded **URIs. For example, if you wish to match “/images/ /test”, then you must use “/images/ /test” to determine the location.

在瀏覽器上顯示的URL 一般都會(huì)進(jìn)行URLEncode ,例如“空格”會(huì)被編碼為 淹朋,但是Nginx 的URL 的匹配都是針對(duì)URLDecode 之后的笙各。也就是說,如果你要匹配“/images/ /test ”础芍,你寫location 的時(shí)候匹配目標(biāo)應(yīng)該是:“/images/ /test ”杈抢。

Example:
location

location  = / {
 #  matches the query / only.
 [ configuration A ]
}
location  / {
  # matches any query, since all queries begin with /, but regular
  # expressions and any longer conventional blocks will be
 # matched first.
 [ configuration B ]
}
location  ^~ /images/ {
  #matches any query beginning with /images/ and halts searching,
 #so regular expressions will not be checked.
 [ configuration C ]
}
location ~* \.(gif|jpg|jpeg)$ {
 # matches any request ending in gif, jpg, or jpeg. However, all
 # requests to the /images/ directory will be handled by
 # Configuration C.  
 [ configuration D ]
}

上述這4 個(gè)location 的配置,沒什么好解釋的仑性,唯一需要說明的是location / {[configuration B]} 惶楼,原文的注釋嚴(yán)格來說是錯(cuò)誤的,但我相信原文作者是了解規(guī)則的诊杆,只是文字描述上簡(jiǎn)化了下歼捐,但這個(gè)簡(jiǎn)化容易給讀者造成“誤解:先檢查正則location ,再檢查普通location ”晨汹。原文:“matches any query, since all queries begin with /, but regular expressions and any longer conventional blocks **will be matched first. ”大意是說:“l(fā)ocation / {} 能夠匹配所有HTTP 請(qǐng)求豹储,因?yàn)槿魏蜨TTP 請(qǐng)求都必然是以‘/ ’開始的(這半句沒有錯(cuò)誤)。但是淘这,正則location 和其他任何比‘/ ’更長(zhǎng)的普通location (location / {} 是普通location 里面最短的剥扣,因此其他任何普通location 都會(huì)比它更長(zhǎng),當(dāng)然location = / {} 和 location ^~ / {} 是一樣長(zhǎng)的)會(huì)優(yōu)先匹配(matched first )慨灭‰Γ” **原文作者說“ but regular expressions will be matched first. ”應(yīng)該只是想說正則 location 會(huì)覆蓋這里的 location / {} ,但依然是普通location / {} 先于正則 location 匹配氧骤,接著再正則 location 匹配呻疹;但其他更長(zhǎng)的普通 location ( any longer conventional blocks )的確會(huì)先于 location / {} 匹配。

Example requests:

  • / -> configuration A
  • /documents/document.html -> configuration B
  • /images/1.gif -> configuration C
  • /documents/1.jpg -> configuration D

Note that you could define these 4 configurations in any order and the results would remain the same.

需要提醒下:這里說“in any order ”和“… remain the same ”是因?yàn)樯厦嬷挥幸粋€(gè)正則location 筹陵。文章前面已經(jīng)說了正則location 的匹配是跟編輯順序有關(guān)系的刽锤。

While nested locations are allowed by the configuration file parser, their use is discouraged and may produce unexpected results.

實(shí)際上 nginx 的配置文件解析程序是允許 location 嵌套定義的( location / { location /uri/ {} } )。但是我們平時(shí)卻很少看見這樣的配置朦佩,那是因?yàn)?nginx 官方并不建議大家這么做并思,因?yàn)檫@樣會(huì)導(dǎo)致很多意想不到的后果。

The prefix “@” specifies a named location. Such locations are not used during normal processing of requests, they are intended only to process internally redirected requests (see **error_page **,**try_files **).

文章開始說了location 的語法中语稠,可以有“= ”宋彼,“^~ ”弄砍,“~ ”和“~* ”前綴,或者干脆沒有任何前綴输涕,還有“@ ”前綴音婶,但是后面的分析我們始終沒有談到“@ ”前綴。文章最后點(diǎn)內(nèi)容莱坎,介紹了“@”的用途:“@ ”是用來定義“Named Location ”的(你可以理解為獨(dú)立于“普通location (location using literal strings )”和“正則location (location using regular expressions )”之外的第三種類型)衣式,這種“Named Location ”不是用來處理普通的HTTP 請(qǐng)求的,它是專門用來處理“內(nèi)部重定向(internally redirected )”請(qǐng)求的檐什。注意:這里說的“內(nèi)部重定向(internally redirected )”或許說成“forward ”會(huì)好點(diǎn)碴卧,以為內(nèi)internally redirected 是不需要跟瀏覽器交互的,純粹是服務(wù)端的一個(gè)轉(zhuǎn)發(fā)行為乃正。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末住册,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子烫葬,更是在濱河造成了極大的恐慌界弧,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件搭综,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡划栓,警方通過查閱死者的電腦和手機(jī)兑巾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忠荞,“玉大人蒋歌,你說我怎么就攤上這事∥海” “怎么了堂油?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)碧绞。 經(jīng)常有香客問我府框,道長(zhǎng),這世上最難降的妖魔是什么讥邻? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任迫靖,我火速辦了婚禮,結(jié)果婚禮上兴使,老公的妹妹穿的比我還像新娘系宜。我一直安慰自己,他們只是感情好发魄,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布盹牧。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪汰寓。 梳的紋絲不亂的頭發(fā)上口柳,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音踩寇,去河邊找鬼啄清。 笑死,一個(gè)胖子當(dāng)著我的面吹牛俺孙,可吹牛的內(nèi)容都是我干的辣卒。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼睛榄,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼荣茫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起场靴,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤啡莉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后旨剥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咧欣,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年轨帜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了魄咕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蚌父,死狀恐怖哮兰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情苟弛,我是刑警寧澤喝滞,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站膏秫,受9級(jí)特大地震影響右遭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜荔睹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一狸演、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧僻他,春花似錦宵距、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽婿斥。三九已至,卻和暖如春哨鸭,著一層夾襖步出監(jiān)牢的瞬間民宿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國打工像鸡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留活鹰,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓只估,卻偏偏與公主長(zhǎng)得像志群,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蛔钙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理锌云,服務(wù)發(fā)現(xiàn),斷路器吁脱,智...
    卡卡羅2017閱讀 134,629評(píng)論 18 139
  • location匹配命令~ #波浪線表示執(zhí)行一個(gè)正則匹配桑涎,區(qū)分大小寫~* #表示執(zhí)行一個(gè)正則匹配,...
    柏樹_Jeff閱讀 595評(píng)論 0 0
  • 前言 最先接觸編程的知識(shí)是在大學(xué)里面,大學(xué)里面學(xué)了一些基礎(chǔ)的知識(shí)遍希,c語言讲衫,java語言,單片機(jī)的匯編語言等孵班;大學(xué)畢...
    oceanfive閱讀 3,048評(píng)論 0 7
  • 1.簡(jiǎn)介: ? Nginx:engine X ,2002年招驴,開源篙程,商業(yè)版? http協(xié)議:web服務(wù)器(類似于ht...
    尛尛大尹閱讀 1,862評(píng)論 0 3
  • 已經(jīng)同步到gitbook,想閱讀的請(qǐng)轉(zhuǎn)到gitbook: Django 1.10 中文文檔 URL dispatc...
    leyu閱讀 14,192評(píng)論 0 16