1. rewrite 作用
rewrite 指令的作用是實現 URL 地址重寫(或跳轉)。Nginx 的 rewrite 規則需要 PCRE 軟件的支持,即通過 Perl 兼容正則表達式語法進行規則匹配。因此需要提前安裝好 PCRE 軟件,同時在編譯安裝 Nginx 的時候應該將 rewrite 模塊開啟,默認編譯時 rewrite 模塊是開啟的,只要你不特殊指定將它關閉。
2. rewrite 語法
rewrite 使用的語法為:
rewrite regex replacement [flag];
語法各部分含義:
rewrite | regex | replacement | [flag] |
---|---|---|---|
指令 | 正則表達式 | 重寫(或跳轉)的 URL 地址 | 標記符號 |
regex 常用正則表達式字符:
flag 標記符號:
flag 標記符號 | 說明 |
---|---|
last | 本條規則匹配完成后,繼續向下匹配新的 location URI 規則,超過10次匹配不到報500錯誤,瀏覽器地址欄 URL 不變(同一站點下) |
break | 本條規則匹配完成即終止,不再匹配后面的任何規則,瀏覽器地址欄 URL 不變(同一站點下) |
redirect | 返回 302 臨時重定向,瀏覽器地址欄會顯示跳轉后的 URL 地址,爬蟲不會更新 URL |
permanent | 返回 301 永久重定向,瀏覽器地址欄會顯示跳轉后的 URL 地址,爬蟲會更新 URL |
注意:
在以上的 flag 標記中,last 和 break 標記功能類似,但二者之間有細微的差別,使用 alias 指令時必須用 last 標記,使用 proxy_pass 指令時要使用 break 標記。last 標記在本條 rewrite 規則 執行完畢后,會對其所在的 server {......} 標簽重新發起請求,而 break 標記則會在本條規則匹配完成后,終止匹配,不再匹配后面的規則。
last 和 break 只有在同一個站點下瀏覽器地址欄 URL 才不變,並且返回 200 狀態碼,如果非同一站點下會返回 302 臨時重定向,並且瀏覽器地址欄會顯示跳轉后的 URL 地址。
同一站點下使用 last 和 break,瀏覽器地址欄 URL 不變:
server {
listen 80;
server_name blog.abc.com;
rewrite /blog.html /index.html last; # 當用戶訪問 http://blog.abc.com/blog.html 時會顯示 http://blog.abc.com/index.html 中的內容,瀏覽器地址欄 URL 不會變
location / {
root html/www;
index index.html index.htm;
}
}
同一站點下使用 redirect 和 permanent,瀏覽器地址欄 URL 變:
server {
listen 80;
server_name blog.abc.com;
rewrite /blog.html /index.html permanent; # 當用戶訪問 http://blog.abc.com/blog.html 時會跳轉到 http://blog.abc.com/index.html ,瀏覽器地址欄 URL 變
location / {
root html/www;
index index.html index.htm;
}
}
3. rewrite 示例
rewrite ^/(.*) http://www.abc.com/$1 permanent;
rewrite 為固定關鍵字,表示開啟一條 rewrite 匹配規則,regex 部分是 ^/(.*) ,這是一個正則表達式,表示匹配所有,匹配成功后跳轉到 http://www.abc.com/$1 。這里的 $1 是取前面 regex 部分括號里的內容,結尾的 permanent 是永久 301 重定向標記,即跳轉到后面的 http:www.abc.com/$1 地址上。
4. rewrite 實戰
4-1. 配置 Nginx rewrite 301 跳轉
www.abc.com 虛擬主機配置:
server {
listen 80;
server_name www.abc.com;
location / {
root html/www;
index index.html index.htm;
}
}
abc.com 虛擬主機配置:
server {
listen 80;
server_name abc.com;
rewrite ^/(.*) http://www.abc.com/$1 permanent; # 當用戶訪問 abc.com 及下面的任意內容時跳轉到 http://www.abc.com/ 對應的地址
location / {
root html/www;
index index.html index.htm;
}
}
實驗結果:
訪問前的地址

訪問后的地址

訪問 http://abc.com/index.html 時跳轉到 http://www.abc.com/index.html ,瀏覽器的地址欄變成了 http://www.abc.com/index.html
4-2. 配置不同域名的 URL 跳轉
www.abc.com 虛擬主機配置:
server {
listen 80;
server_name www.abc.com;
location / {
root html/www;
index index.html index.htm;
}
}
在html/www文件夾下面創建blog文件夾,並在blog文件夾下面創建index.html文件,文件內容為:http://www.abc.com/blog/
blog.abc.com 虛擬主機配置:
server {
listen 80;
server_name blog.abc.com;
location / {
root html/blog;
index index.html index.htm;
}
if ( $http_host ~* "^(.*)\.abc\.com$") {
set $domain $1;
rewrite ^/(.*) http://www.abc.com/$domain/$1 permanent; # 當用戶訪問 blog.abc.com 及下面的任意內容時跳轉到 http://www.abc.com/blog/ 對應的地址
}
}
實驗結果:
訪問前的地址

訪問后的地址

訪問 http://blog.abc.com/index.html 時跳轉到 http://www.abc.com/blog/index.html ,瀏覽器的地址欄變成了 http://www.abc.com/blog/index.html
5. 總結
使用 alias 指令時必須用 last 標記,使用 proxy_pass 指令時要使用 break 標記。
在根 location(即 location / {......})中 或者 server{......} 標簽中編寫 rewrite 規則,使用 last 標記比較好, 因為如果有.php等 fastcgi 請求還要繼續處理,而在普通的 location(例 location /oldboy/ {......} 或 if{})中編寫 rewrite 規則,則建議使用 break 標記。
6. 參考資料
http://tengine.taobao.org/nginx_docs/cn/docs/http/ngx_http_rewrite_module.html#rewrite
https://www.cnblogs.com/fengchi/p/6525021.html
https://www.cnblogs.com/mikeluwen/p/7068279.html
https://blog.csdn.net/sunyuhua_keyboard/article/details/78273700