Nginx之location 匹配規則詳解


參考
https://www.cnblogs.com/lidabo/p/4169396.html

原文寫的很棒,謝謝前輩,現做排版整理

一、關於一些對location認識的誤區

1、 location 的匹配順序是“先匹配正則,再匹配普通”。

矯正: location 的匹配順序其實是“先匹配普通,再匹配正則”。我這么說,大家一定會反駁我,因為按“先匹配普通,再匹配正則”解釋不了大家平時習慣的按“先匹配正則,再匹配普通”的實踐經驗。這里我只能暫時解釋下,造成這種誤解的原因是:正則匹配會覆蓋普通匹配(實際的規則,比這復雜,后面會詳細解釋)。

2、 location 的執行邏輯跟 location 的編輯順序無關。

矯正:這句話不全對,“普通 location ”的匹配規則是“最大前綴”,因此“普通 location ”的確與 location 編輯順序無關;

但是“正則 location ”的匹配規則是“順序匹配,且只要匹配到第一個就停止后面的匹配”;

“普通location ”與“正則 location ”之間的匹配順序是?
先匹配普通 location ,再“考慮”匹配正則 location 。
注意這里的“考慮”是“可能”的意思,也就是說匹配完“普通 location ”后,有的時候需要繼續匹配“正則 location ”,有的時候則不需要繼續匹配“正則 location ”。兩種情況下,不需要繼續匹配正則 location :
( 1 )當普通 location 前面指定了“ ^~ ”,特別告訴 Nginx 本條普通 location 一旦匹配上,則不需要繼續正則匹配;
( 2 )當普通location 恰好嚴格匹配上,不是最大前綴匹配,則不再繼續匹配正則。

總結一句話: “正則 location 匹配讓步普通 location 的嚴格精確匹配結果;但覆蓋普通 location 的最大前綴匹配結果”

官方文檔解釋
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/ { … }
依據不同的前綴“= ”,“^~ ”,“~ ”,“~* ”和不帶任何前綴的(因為[A] 表示可選,可以不要的),表達不同的含義, 簡單的說盡管location 的/uri/ 配置一樣,但前綴不一樣,表達的是不同的指令含義。
2 、查詢字符串不在URI范圍內。例如:/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:
“~” for case sensitive matching
“~*” for case insensitive matching

譯文:上文講到location /uri/ 可通過使用不同的前綴,表達不同的含義。對這些不同前綴,分下類,就2 大類:正則location ,英文說法是location using regular expressions 和普通location ,英文說法是location using literal strings 。
那么其中“~ ”和“~* ”前綴表示正則location ,“~ ”區分大小寫,“~* ”不區分大小寫;
其他前綴(包括:“=”,“^~ ”和“@ ”)和無任何前綴的都屬於普通location 。

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

譯文:對於一個特定的 HTTP 請求( a particular query ), nginx 應該匹配哪個 location 塊的指令呢(注意:我們在 nginx.conf 配置文件里面一般會定義多個 location 的)?
匹配規則是:先匹配普通location (再匹配正則表達式)。注意:官方文檔這句話就明確說了,先普通location ,而不是有些同學的誤區“先匹配正則location ”。

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

前面說了“普通location ”與“正則location ”之間的匹配規則是:
先匹配普通location ,再匹配正則location。
那么,“普通location ”內部(普通location 與普通location )是如何匹配的呢?
簡單的說:最大前綴匹配.
原文:
1、match the beginning portion of the query (說的是匹配URI 的前綴部分beginning portion );
2 、the most specific match will be used (因為location 不是“嚴格匹配”,而是“前綴匹配”,就會產生一個HTTP 請求,可以“前綴匹配”到多個普通location
例如:location /prefix/mid/ {} 和location /prefix/ {} ,對於HTTP 請求/prefix/mid/t.html ,前綴匹配的話兩個location 都滿足,選哪個?
原則是: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 先匹配,而且選擇了最大前綴匹配后,不能就停止后面的匹配,最大前綴匹配只是一個臨時的結果,nginx 還需要繼續檢查正則location (但至於最終匹配的是普通location 的最大前綴匹配,還是正則location 的匹配,截止當前的內容還沒講,但后面會講)。
第二層是“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”內部的匹配規則是:按照正則location 在配置文件中的物理順序(編輯順序)匹配的(這句話就說明location 並不是一定跟順序無關
只是普通location 與順序無關,正則location 還是與順序有關的)
並且只要匹配到一條正則location ,就不再考慮后面的(這與“普通location ”與“正則location ”之間的規則不一樣
“普通location ”與“正則location ”之間的規則是:選擇出“普通location ”的最大前綴匹配結果后,還需要繼續搜索正則location )。

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

這句話回答了“普通location ”的最大前綴匹配結果與繼續搜索的“正則location ”匹配結果的決策關系。
如果繼續搜索的“正則location ”也有匹配上的,那么“正則location ”覆蓋 “普通location ”的最大前綴匹配(因為有這個覆蓋關系,所以造成有些同學以為正則location 先於普通location 執行的錯誤理解);
但是如果“正則location ”沒有能匹配上,那么就用“普通location ”的最大前綴匹配結果。

阻止繼續搜索正則location

通常的規則是,匹配完了“普通location ”指令,還需要繼續匹配“正則location ”,但是你也可以告訴Nginx :匹配到了“普通location ”后,不再需要繼續匹配“正則location ”了,要做到這一點只要在“普通location ”前面加上“^~ ”符號(^ 表示“非”,~ 表示“正則”,字符意思是:不要繼續匹配正則)。

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 “location = /” will speed up processing of this request a bit as search will stop after first comparison.

除了上文的“^~ ”可以阻止繼續搜索正則location 外,你還可以加“= ”。那么如果“^~ ”和“= ”都能阻止繼續搜索正則location 的話,那它們之間有什么區別呢?
區別很簡單,共同點是它們都能阻止繼續搜索正則location ,不同點是“^~ ”依然遵守“最大前綴”匹配規則,然而“= ”不是“最大前綴”,而是必須是嚴格匹配(exact match )。

這里順便講下“location / {} ”和“location = / {} ”的區別
“location / {} ”遵守普通location 的最大前綴匹配,由於任何URI 都必然以“/ ”根開頭,所以對於一個URI ,如果有更specific 的匹配,那自然是選這個更specific 的,如果沒有,“/ ”一定能為這個URI 墊背(至少能匹配到“/ ”),也就是說“location / {} ”有點默認配置的味道,其他更specific的配置能覆蓋overwrite 這個默認配置(這也是為什么我們總能看到location / {} 這個配置的一個很重要的原因)。
而“location = / {} ”遵守的是“嚴格精確匹配exact match ”,也就是只能匹配 http://host:port/ 請求,同時會禁止繼續搜索正則location 。
因此如果我們只想對“GET / ”請求配置作用指令,那么我們可以選“location = / {} ”這樣能減少正則location 的搜索,因此效率比“location / {}” 高(注:前提是我們的目的僅僅只想對“GET / ”起作用)。

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

前面我們說了,普通location 匹配完后,還會繼續匹配正則location ;但是nginx 允許你阻止這種行為,方法很簡單,只需要在普通location 前加“^~ ”或“= ”。但其實還有一種“隱含”的方式來阻止正則location 的搜索,這種隱含的方式就是:當“最大前綴”匹配恰好就是一個“嚴格精確(exact match )”匹配,照樣會停止后面的搜索。原文字面意思是:只要遇到“精確匹配exact match ”,即使普通location 沒有帶“= ”或“^~ ”前綴,也一樣會終止后面的匹配。

先舉例解釋下,后面例題會用實踐告訴大家。

假設當前配置是:
    location /exact/match/test.html 
        { 配置指令塊1}
    location /prefix/ 
        { 配置指令塊2} 
        和 
    location ~ \.html$ 
        { 配置指令塊3}

如果我們請求 GET /prefix/index.html ,則會被匹配到指令塊3 ,因為普通location /prefix/ 依據最大匹配原則能匹配當前請求,但是會被后面的正則location覆蓋;

當請求GET /exact/match/test.html ,會匹配到指令塊1 ,因為這個是普通location 的exact match ,會禁止繼續搜索正則location 。

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

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 一般都會進行URLEncode ,例如“空格”會被編碼為 ,但是Nginx 的URL 的匹配都是針對URLDecode 之后的。
也就是說,如果你要匹配“/images/ /test ”,你寫location 的時候匹配目標應該是:“/images/ /test ”。

Example:

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 個location 的配置,沒什么好解釋的,唯一需要說明的是location / {[configuration B]} ,原文的注釋嚴格來說是錯誤的,但我相信原文作者是了解規則的,只是文字描述上簡化了下,但這個簡化容易給讀者造成“誤解:先檢查正則location ,再檢查普通location ”。
原文:“matches any query, since all queries begin with /, butregular expressions and any longer conventional blocks will be matched first. ”大意是說:“location / {} 能夠匹配所有HTTP 請求,因為任何HTTP 請求都必然是以‘/ ’開始的(這半句沒有錯誤)。
但是,正則location 和其他任何比‘/ ’更長的普通location (location / {} 是普通location 里面最短的,因此其他任何普通location 都會比它更長,當然location = / {} 和 location ^~ / {} 是一樣長的)會優先匹配(matched first )。” 原文作者說“ but regular expressions will be matched first. ”應該只是想說正則 location 會覆蓋這里的 location / {} ,但依然是普通location / {} 先於正則 location 匹配,接着再正則 location 匹配;
但其他更長的普通 location ( any longer conventional blocks )的確會先於 location / {} 匹配。


nginx 的配置文件解析程序是允許 location 嵌套定義的( location / { location /uri/ {} } )。但是我們平時卻很少看見這樣的配置,那是因為 nginx 官方並不建議大家這么做,因為這樣會導致很多意想不到的后果。

“@”用途

“@ ”是用來定義“Named Location ”的(你可以理解為獨立於“普通location (location using literal strings )”和“正則location (location using regular expressions )”之外的第三種類型),這種“Named Location ”不是用來處理普通的HTTP 請求的,它是專門用來處理“內部重定向(internally redirected )”請求的。
注意:這里說的“內部重定向(internally redirected )”或許說成“forward ”會好點,因為內internally redirected 是不需要跟瀏覽器交互的,純粹是服務端的一個轉發行為。


location 實例練習

Nginx 的語法形式是:

location [=|\~|\~*|^~|@] /uri/ 
    { … } 
    意思是可以以“ = ”或“ ~\* ”或“ ~ ”或“ ^~ ”或“ @ ”符號為前綴
    當然也可以沒有前綴(因為 [A] 是表示可選的 A ; A|B 表示 A 和 B 選一個)
    緊接着是 /uri/ ,再接着是{…} 指令塊
    整個意思是對於滿足這樣條件的 /uri/ 適用指令塊 {…} 的指令。

其中“普通 location ”是以“ = ”或“ ^~ ”為前綴或者沒有任何前綴的 /uri/ ;“正則 location ”是以“ ~ ”或“ ~* ”為前綴的 /uri/ 。

那么,當我們在一個 server 上下文編寫了多個 location 的時候, Nginx 對於一個 HTTP 請求,是如何匹配到一個 location 做處理呢?

用一句話簡單概括 Nginx 的 location 匹配規則是:“正則 location ”讓步 “普通 location”的嚴格精確匹配結果;但覆蓋 “普通 location ”的最大前綴匹配結果。

理解這句話,我想通過下面的實例來說明。

1.先普通 location ,再正則 location

普通 location 的匹配結果又分兩種:一種是“嚴格精確匹配”,另一種是“最大前綴匹配”

例題 1 :假設 nginx 的配置如下


server {

       listen       9090;

       server_name  localhost;

                  location / {

           root   html;

           index  index.html index.htm;

           deny all;

       }

       location ~ \.html$ {

           allow all;

       }

}
上述配置的意思是:
location / {… deny all;} 
    普通 location 以“ / ”開始的 URI 請求
    (注意任何 HTTP 請求都必然以“/ ”開始,所以“ / ”的意思是所有的請求都能被匹配上),都拒絕訪問;

location ~\.html$ {allow all;} 正則 location以 .html 結尾的 URI 請求,都允許訪問。

測試結果如下:

URI     請求	                                HTTP 響應
curl http://localhost:9090/	                    403 Forbidden
curl http://localhost:9090/index.html	        Welcome to nginx!
curl http://localhost:9090/index_notfound.html	404 Not Found


curl http://localhost:9090/ 的結果是“ 403 Forbidden ”,說明被匹配到“ location / {..deny all;} ”了,原因很簡單HTTP 請求 GET / 被“嚴格精確”匹配到了普通 location / {} ,則會停止搜索正則 location ;

curl http://localhost:9090/index.html 結果是“ Welcome to nginx! ”,說明沒有被“ location / {…deny all;} ”匹配,否則會 403 Forbidden ,但 /index.html 的確也是以“ / ”開頭的,只不過此時的普通 location / 的匹配結果是“最大前綴”匹配,所以 Nginx 會繼續搜索正則 location , location ~ \.html$ 表達了以 .html 結尾的都 allow all; 於是接着就訪問到了實際存在的 index.html 頁面。

curl http://localhost:9090/index_notfound.html   同樣的道理先匹配 location / {} ,但屬於“普通 location 的最大前綴匹配”,於是后面被“正則 location ” location ~ \.html$ {} 覆蓋了,最終 allow all ; 但的確目錄下不存在index_notfound.html 頁面,於是 404 Not Found 。

如果此時我們訪問 http://localhost:9090/index.txt 會是什么結果呢?
顯然是 deny all ;
因為先匹配上了 location / {..deny all;} 盡管屬於“普通 location ”的最大前綴匹配結果,繼續搜索正則 location ,但是 /index.txt 不是以 .html結尾的,正則 location 失敗,最終采納普通 location 的最大前綴匹配結果,於是 deny all 了。

2.普通 location 的“隱式”嚴格匹配

例題 2 :我們在例題 1 的基礎上增加精確配置

server {

       listen       9090;

       server_name  localhost;

                  location /exact/match.html {

                        allow all;

       }

                  location / {

                       root   html;
            
                       index  index.html index.htm;
            
                       deny all;

       }

                   location ~ \.html$ {
            
                       allow all;

       }

}

 

測試請求:

[root@web108 ~]# curl http://localhost:9090/exact/match.html
                返回404

結果進一步驗證了“普通 location ”的“嚴格精確”匹配會終止對正則 location 的搜索。
這里我們小結下“普通 location”與“正則 location ”的匹配規則:
先匹配普通 location ,再匹配正則 location ,但是如果普通 location 的匹配結果恰好是“嚴格精確( exact match )”的,則 nginx 不再嘗試后面的正則 location ;如果普通 location 的匹配結果是“最大前綴”,則正則 location 的匹配覆蓋普通 location 的匹配。
也就是前面說的“正則 location 讓步普通location 的嚴格精確匹配結果,但覆蓋普通 location 的最大前綴匹配結果”。

3.普通 location 的“顯式”嚴格匹配和“ ^~ ” 前綴

上面我們演示的普通 location 都是不加任何前綴的,其實普通 location 也可以加前綴:“ ^~ ”和“ = ”。
其中“ ^~”的意思是“非正則,不需要繼續正則匹配”,也就是通常我們的普通 location ,還會繼續搜索正則 location (恰好嚴格精確匹配除外)
但是 nginx 很人性化允許配置人員告訴 nginx 某條普通 location ,無論最大前綴匹配,還是嚴格精確匹配都終止繼續搜索正則 location ;
而“ = ”則表達的是普通 location 不允許“最大前綴”匹配結果,必須嚴格等於,嚴格精確匹配。

例題 3 :“ ^~ ”前綴的使用


server {

       listen       9090;

       server_name  localhost;

                    location /exact/match.html {

                    allow all;

       }

                    location ^~ / {

                    root   html;

                       index  index.html index.htm;
            
                       deny all;

       }

                    location ~ \.html$ {

                    allow all;

       }

}

 

把例題 2 中的 location / {} 修改成 location ^~ / {} ,再看看測試結果:

URI 請求	                        修改前	                修改后
curl http://localhost:9090/	    403 Forbidden	            403 Forbidden
curl http://localhost:9090/index.html	Welcome to nginx!	403 Forbidden
curl http://localhost:9090/index_notfound.html	404 Not Found	403 Forbidden
curl http://localhost:9090/exact/match.html	404 Not Found	404 Not Found

除了 GET /exact/match.html 是 404 Not Found ,其余都是 403 Forbidden
原因很簡單所有請求都是以“ / ”開頭,所以所有請求都能匹配上“ / ”普通 location ,但普通 location 的匹配原則是“最大前綴”,所以只有/exact/match.html 匹配到 location /exact/match.html {allow all;} ,其余都 location ^~ / {deny all;} 並終止正則搜索。

例題 4 :“ = ”前綴的使用

server {

       listen       9090;

       server_name  localhost;

                  location /exact/match.html {

           allow all;

       }

                 location = / {

           root   html;

           index  index.html index.htm;

           deny all;

       }

       location ~ \.html$ {

           allow all;

       }

}

例題 4 相對例題 2 把 location / {} 修改成了 location = / {} ,再次測試結果:

URI 請求	                            修改前	        修改后
curl http://localhost:9090/	            403 Forbidden	403 Forbidden
curl http://localhost:9090/index.html	Welcome to nginx!	Welcome to nginx!
curl http://localhost:9090/index_notfound.html	404 Not Found	404 Not Found
curl http://localhost:9090/exact/match.html	404 Not Found	404 Not Found
curl http://localhost:9090/test.jsp	403 Forbidden	404 Not Found
 

最能說明問題的測試是 GET /test.jsp ,實際上 /test.jsp 沒有匹配正則 location ( location ~\.html$ ),
也沒有匹配 location = / {} ,如果按照 location / {} 的話,會“最大前綴”匹配到普通 location / {} ,結果是 deny all 。

4.正則 location 與編輯順序

對於普通 location 指令,匹配規則是:最大前綴匹配(與順序無關),如果恰好是嚴格精確匹配結果或者加有前綴“ ^~ ”或“ = ”(符號“ = ”只能嚴格匹配,不能前綴匹配),則停止搜索正則 location ;
但對於正則 location 的匹配規則是:按編輯順序逐個匹配(與順序有關),只要匹配上,就立即停止后面的搜索。

配置 3.1

server {

       listen       9090;

       server_name  localhost;

 

       location ~ \.html$ {

           allow all; 

       }  

 

       location ~ ^/prefix/.*\.html$ {

           deny all;  

       }  

 

}

配置 3.2

server {

       listen       9090;

       server_name  localhost;

 

      

       location ~ ^/prefix/.*\.html$ {

           deny all;  

       }  

                 

        location ~ \.html$ {

           allow all; 

       } 

 

}

 

測試結果:

URI 請求	                                配置 3.1	    配置 3.2
curl http://localhost:9090/regextest.html	404 Not Found	404 Not Found
curl http://localhost:9090/prefix/regextest.html	404 Not Found	403 Forbidden
 

解釋:

Location ~ ^/prefix/.*\.html$ {deny all;} 
表示正則 location 對於以 /prefix/ 開頭, .html 結尾的所有 URI 請求,都拒絕訪問;   
location ~\.html${allow all;} 表示正則 location 對於以 .html 結尾的 URI 請求,都允許訪問。 
實際上,prefix 的是 ~\.html$ 的子集。

在“配置 3.1 ”下,兩個請求都匹配上 location ~\.html$ {allow all;} ,並且停止后面的搜索,於是都允許訪問, 404 Not Found ;
在“配置 3.2 ”下, /regextest.html 無法匹配 prefix ,於是繼續搜索 ~\.html$ ,允許訪問,於是 404 Not Found ;
然而 /prefix/regextest.html 匹配到 prefix ,於是 deny all , 403 Forbidden 。
配置 3.3

server {

       listen       9090;

       server_name  localhost;

 

       location  /prefix/ {

               deny all;  

       }  

          

       location  /prefix/mid/ {

               allow all; 

       }  

 

}

配置 3.4

server {

       listen       9090;

       server_name  localhost;

 

     

       location  /prefix/mid/ {

               allow all; 

       }  

                  location  /prefix/ {

               deny all;  

       }  

}

測試結果:

URI 請求	配置 3.1	配置 3.2
curl http://localhost:9090/prefix/t.html	403 Forbidden	403 Forbidden
curl http://localhost:9090/prefix/mid/t.html	404 Not Found	404 Not Found


測試結果表明:普通 location 的匹配規則是“最大前綴”匹配,而且與編輯順序無關。

5.“@” 前綴 Named Location 使用

REFER: http://wiki.nginx.org/HttpCoreModule#error_page

假設配置如下:

server {

       listen       9090;

       server_name  localhost;

 

        location  / {

           root   html;

           index  index.html index.htm;

           allow all;

       }

       #error_page 404 http://www.baidu.com # 直接這樣是不允許的

       error_page 404 = @fallback;

 

       location @fallback {

           proxy_pass http://www.baidu.com;

       }

}

 

上述配置文件的意思是:如果請求的 URI 存在,則本 nginx 返回對應的頁面;
如果不存在,則把請求代理到baidu.com 上去做個彌補
(注: nginx 當發現 URI 對應的頁面不存在, HTTP_StatusCode 會是 404 ,此時error_page 404 指令能捕獲它)。

 

測試一:
[root@web108 ~]# curl http://localhost:9090/nofound.html -i
HTTP/1.1 302 Found
Server: nginx/1.1.0
Date: Sat, 06 Aug 2011 08:17:21 GMT
Content-Type: text/html; charset=iso-8859-1
Location: http://localhost:9090/search/error.html
Connection: keep-alive
Cache-Control: max-age=86400
Expires: Sun, 07 Aug 2011 08:17:21 GMT
Content-Length: 222
<!DOCTYPE HTML PUBLIC “-//IETF//DTD HTML 2.0//EN”>
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href=”http://www.baidu.com/search/error.html”>here</a>.</p>
</body></html>
當我們 GET /nofound.html 發送給本 nginx , nginx 找不到對應的頁面,於是 error_page 404 = @fallback ,請求被代理到 http://www.baidu.com ,於是 nginx 給 http://www.baidu.com 發送了 GET /nofound.html ,但/nofound.html 頁面在百度也不存在,百度 302 跳轉到錯誤頁。

直接訪問 http://www.baidu.com/nofound.html 結果:

[root@web108 ~]# curl http://www.baidu.com/nofound.html -i
HTTP/1.1 302 Found
Date: Sat, 06 Aug 2011 08:20:05 GMT
Server: Apache
Location: http://www.baidu.com/search/error.html
Cache-Control: max-age=86400
Expires: Sun, 07 Aug 2011 08:20:05 GMT
Content-Length: 222
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC “-//IETF//DTD HTML 2.0//EN”>
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href=”http://www.baidu.com/search/error.html”>here</a>.</p>
</body></html>

測試二:訪問一個 nginx 不存在,但 baidu 存在的頁面

[root@web108 ~]# curl http://www.baidu.com/duty/ -i

HTTP/1.1 200 OK

Date: Sat, 06 Aug 2011 08:21:56 GMT

Server: Apache

P3P: CP=” OTI DSP COR IVA OUR IND COM ”

P3P: CP=” OTI DSP COR IVA OUR IND COM ”

Set-Cookie: BAIDUID=5C5D2B2FD083737A0C88CA7075A6601A:FG=1; expires=Sun, 05-Aug-12 08:21:56 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1

Set-Cookie: BAIDUID=5C5D2B2FD083737A2337F78F909CCB90:FG=1; expires=Sun, 05-Aug-12 08:21:56 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1

Last-Modified: Wed, 05 Jan 2011 06:44:53 GMT

ETag: “d66-49913b8efe340″

Accept-Ranges: bytes

Content-Length: 3430

Cache-Control: max-age=86400

Expires: Sun, 07 Aug 2011 08:21:56 GMT

Vary: Accept-Encoding,User-Agent

Connection: Keep-Alive

Content-Type: text/html

 

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”

“http://www.w3.org/TR/html4/loose.dtd”>

。。。。

</body>

</html>

顯示,的確百度這個頁面是存在的。

[root@web108 ~]# curl http://localhost:9090/duty/ -i

HTTP/1.1 200 OK

Server: nginx/1.1.0

Date: Sat, 06 Aug 2011 08:23:23 GMT

Content-Type: text/html

Connection: keep-alive

P3P: CP=” OTI DSP COR IVA OUR IND COM ”

P3P: CP=” OTI DSP COR IVA OUR IND COM ”

Set-Cookie: BAIDUID=8FEF0A3A2C31D277DCB4CC5F80B7F457:FG=1; expires=Sun, 05-Aug-12 08:23:23 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1

Set-Cookie: BAIDUID=8FEF0A3A2C31D277B1F87691AFFD7440:FG=1; expires=Sun, 05-Aug-12 08:23:23 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1

Last-Modified: Wed, 05 Jan 2011 06:44:53 GMT

ETag: “d66-49913b8efe340″

Accept-Ranges: bytes

Content-Length: 3430

Cache-Control: max-age=86400

Expires: Sun, 07 Aug 2011 08:23:23 GMT

Vary: Accept-Encoding,User-Agent

 

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”

“http://www.w3.org/TR/html4/loose.dtd”>

<html>

。。。

</body>

</html>

當 curl http://localhost:9090/duty/ -i 時, nginx 沒找到對應的頁面,於是 error_page = @fallback ,把請求代理到 baidu.com 。
注意這里的 error_page = @fallback 不是靠重定向實現的,而是所說的“ internally redirected (forward )”。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM