參考
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 )”。