總結: rewrite 可以在 server location 塊, 正則比配的時候才重寫,是以多條 rewrite 順序靠前且比對的優先執行。
break跳出rewrite階段,不會在比對,進入輸出階段。 last 類似重新發起請求,是以會重新進行比對。
轉自:http://blog.sina.com.cn/s/blog_4f9fc6e10102ux0w.html
http://blog.cafeneko.info/2010/10/nginx_rewrite_note/ 或者 http://yuanhsh.iteye.com/blog/1321982
nginx 的官方注釋是這樣的:
last
stops processing the current set of ngx_http_rewrite_module directives followed by a search for a new location matching the changed URI;
break
stops processing the current set of ngx_http_rewrite_module directives;
我們知道nginx運作分十一個執行階段,上面說提到的ngx_http_rewrite_mode,可以了解為其中一個階段-rewrite階段。
typedef enum {
NGX_HTTP_POST_READ_PHASE = 0,
NGX_HTTP_SERVER_REWRITE_PHASE,
NGX_HTTP_FIND_CONFIG_PHASE,
NGX_HTTP_REWRITE_PHASE, //rewrite階段在這裡
NGX_HTTP_POST_REWRITE_PHASE,
NGX_HTTP_PREACCESS_PHASE,
NGX_HTTP_ACCESS_PHASE,
NGX_HTTP_POST_ACCESS_PHASE,
NGX_HTTP_TRY_FILES_PHASE,
NGX_HTTP_CONTENT_PHASE,
NGX_HTTP_LOG_PHASE
} ngx_http_phases;
是以我們再來了解last與break的差別:
last: 停止目前這個請求,并根據rewrite比對的規則重新發起一個請求。新請求又從第一階段開始執行…
break:相對last,break并不會重新發起一個請求,隻是跳過目前的rewrite階段,并執行本請求後續的執行階段…
我們來看一個例子:
server {
listen 80 default_server;
server_name dcshi.com;
root www;
location /break/ {
rewrite ^/break/(.*) /test/$1 break;
echo "break page";
}
location /last/ {
rewrite ^/last/(.*) /test/$1 last;
echo "last page";
}
location /test/ {
echo "test page";
}
}
請求:http://dcshi.com/break/***
輸出: break page
分析:正如上面讨論所說,break是跳過目前請求的rewrite階段,并繼續執行本請求的其他階段,很明顯,對于/foo 對應的content階段的輸出為 echo “break page”; (content階段,可以簡單了解為産生資料輸出的階段,如傳回靜态頁面内容也是在content階段;echo指令也是運作在content階段,一般情況下content階段隻能對應一個輸出指令,如同一個location配置兩個echo,最終隻會有一個echo指令被執行);當然如果你把/break/裡的echo 指令注釋,然後再次通路/break/xx會報404,這也跟我們預期一樣:雖然/break/xx被重定向到/test/xx,但是break指令不會重新開啟一個新的請求繼續比對,是以nginx是不會比對到下面的/test/這個location;在echo指令被注釋的情況下,/break/ 這location裡隻能執行nginx預設的content指令,即嘗試找/test/xx這個html頁面并輸出起内容,事實上,這個頁面不存在,是以會報404的錯誤。
請求: http://dcshi.com/last/***
輸出: test page
分析: last與break最大的不同是,last會重新發起一個新請求,并重新比對location,是以對于/last,重新比對請求以後會比對到/test/,是以最終對應的content階段的輸出是test page;
假設你對nginx的運作階段有一個大概的了解,對了解last與break就沒有問題了。
location ~ ^/testtest/ {
default_type text/html;
echo 111;
}
rewrite ^/testtest/ /test.php last;