ngx_http_rewrite_module
- nginx中
ngx_http_rewrite_module
模塊提供URI重寫功能 ,通過正則表達(dá)式匹配目標(biāo)URI,再重寫URI請(qǐng)求。 - 這個(gè)模塊包含
break、if、return、rewrite、set
指令。
break指令
- 用于停止處理當(dāng)前
ngx_http_rewrite_module
指令集。
return指令
- 用于停止處理并立即返回到客戶端,非標(biāo)準(zhǔn)狀態(tài)碼444會(huì)導(dǎo)致連接關(guān)閉。
- 從0.8.42版本開始,可以返回重定向(狀態(tài)碼為:301,302,303,307,308),重定向的URI可以是當(dāng)前服務(wù)中的URI,完整的URL根據(jù)請(qǐng)求協(xié)議
$scheme
生成??梢苑祷仨憫?yīng)內(nèi)容,響應(yīng)內(nèi)容和重定向的URL中可以包含變量。 - 可以用在
server,location,if
塊中。 - 在0.7.51以前的版本只能返回以下指定的狀態(tài)碼:204,400,402,406,408,410,411,413,416,500,504。
- 1.1.16和1.0.13以前的版本中307不當(dāng)作重定向處理。
- 1.13.0以前的版本中308不當(dāng)作重定向處理。
return code [text];
返回狀態(tài)碼和響應(yīng)內(nèi)容。return code URL;
返回重定向,code只能為301,302,303,307,308。return URL;
返回重定向,狀態(tài)碼默認(rèn)為302。
- 配置文件
server {
listen 86;
server_name 192.168.1.166;
location /home {
return 200 "home page";
}
location /index {
return 301 /home;
}
location /baidu {
return https://www.baidu.com;
}
}
- 請(qǐng)求:
GET http://192.168.1.166:86/home
,響應(yīng):200 home page
- 請(qǐng)求:
GET http://192.168.1.166:86/index
,響應(yīng):301 http://192.168.1.166:86/home
- 請(qǐng)求:
GET http://192.168.1.166:86/baidu
,響應(yīng):302 https://www.baidu.com
rewrite指令
- 語法:
rewrite regex replacement [flag];
,rewrite
指令按它在配置文件中出現(xiàn)的先后順序執(zhí)行。 - 正則表達(dá)式匹配成功URI后按
replacement
設(shè)置的文本替換原URI,如果replacement替換文本以http://或https://或$scheme開頭則會(huì)停止處理并返回給客戶端重定向。 - 可以用在
server, location, if
塊中。 - 可以使用
flag
來終止指令進(jìn)一步執(zhí)行。flag
可以為: last
,停止處理當(dāng)前指令集,搜索新的location
,使用新的uri直接響應(yīng),響應(yīng)狀態(tài)碼由新的uri確定,而不是返回重定向。break
,停止處理當(dāng)前指令集,但不會(huì)搜索新的location
。redirect
,如果replacement
不以http://
https://
$scheme
開頭返回臨時(shí)重定向,狀態(tài)碼為302。permanent
,返回永久重定向,狀態(tài)碼為301。
rewrite
配合last
,rewrite
正則表達(dá)式匹配成功后會(huì)繼續(xù)搜索location
,搜索到以后使用新的uri直接響應(yīng),而并不會(huì)向客戶端返回重定向的響應(yīng)。配置文件
server {
rewrite_log on;
# 配置后日志中可查看重寫前后的uri
error_log /usr/local/nginx/logs/error.log notice;
listen 86;
server_name 192.168.1.166;
location ~ ^/music/(\d+)\.mp3$ {
return 200 "/music/$1.mp3";
}
location ~ ^/video/(\d+)\.mp4$ {
return 200 "/video/$1.mp4";
}
# server塊內(nèi)的rewrite
rewrite ^/download/mp3/(\d+)\.mp3$ /music/$1.mp3 last;
rewrite ^/download/mp4/(\d+)\.mp4$ /video/$1.mp4 last;
}
請(qǐng)求:GET http://192.168.1.166:86/download/mp3/001.mp3
,響應(yīng):200 /music/001.mp3
,這里狀態(tài)碼是200而不是3打頭的重定向,效果類似于代理。
請(qǐng)求:GET http://192.168.1.166:86/download/mp4/001.mp4
,響應(yīng):200 /video/001.mp4
,這里狀態(tài)碼是200而不是3打頭的重定向。
rewrite
配合break
,匹配成功后不會(huì)從location
中搜索而是嘗試從文件系統(tǒng)中讀取- 配置文件
server {
rewrite_log on;
error_log /usr/local/nginx/logs/error.log notice;
listen 86;
server_name 192.168.1.166;
location ~ ^/music/(\d+)\.mp3$ {
return 200 "/music/$1.mp3";
}
location ~ ^/video/(\d+)\.mp4$ {
return 200 "/video/$1.mp4";
}
location /download/ {
rewrite ^/download/mp3/(\d+)\.mp3$ /music/$1.mp3 break;
rewrite ^/download/mp4/(\d+)\.mp4$ /video/$1.mp4 break;
}
}
- 請(qǐng)求:
GET http://192.168.1.166:86/download/mp3/001.mp3
,響應(yīng):404 Not Found
。
- 處理過程:
/download/mp3/001.mp3
重寫為/music/001.mp3
,但不會(huì)匹配別的location
而是嘗試從文件目錄/usr/local/nginx/html/music/001.mp3
中讀取,站點(diǎn)根目錄下沒有這個(gè)文件所以返回404。
- nginx日志:
^/download/mp3/(\d+)\.mp3$" matches "/download/mp3/001.mp3
,rewritten data: "/music/001.mp3
,open() "/usr/local/nginx/html/music/001.mp3" failed (2: No such file or directory)
。
- 配置文件
server {
rewrite_log on;
error_log /usr/local/nginx/logs/error.log notice;
listen 86;
server_name 192.168.1.166;
location /test1 {
rewrite ^/test1/(.+)$ /test2/$1 last;
}
location /test2 {
rewrite ^/test2/(.+)$ /test3/$1;
return 200 "/test2/$1";
}
location /test3 {
return 200 "/test3";
}
}
- 請(qǐng)求:
http://192.168.1.166:86/test1/order
,響應(yīng):200 /test2/order
。
- 處理過程:
/test1/order
在/test1
塊中被重寫為/test2/order
,進(jìn)入/test2
塊中后被重寫為/test3/order
但因?yàn)?/span>rewrite ^/test2/(.+)$ /test3/$1;
后沒有break
所以執(zhí)行了塊內(nèi)下一句return 200 "/test2/$1";
,$1匹配的是order因此返回/test2/order
。
- 修改
/test2
塊內(nèi)的配置,重定向以后break從而停止當(dāng)前塊內(nèi)的處理,配置文件: location /test2 {
rewrite ^/test2/(.+)$ /test3/$1 break;
return 200 "/test2/$1";
}
- 準(zhǔn)備測試文件,
echo "1.html" > /usr/local/nginx/html/test3/1.html
- 請(qǐng)求:
GET http://192.168.1.166:86/test1/1.html
,響應(yīng):200 1.html
- 處理過程:
/test2
塊中重寫為/test3/1.html
,break以后不會(huì)搜索別的location因此沒有進(jìn)入/test3
塊內(nèi),而是從文件目錄中讀取1.html返回。
配置文件
server {
rewrite_log on;
error_log /usr/local/nginx/logs/error.log notice;
listen 86;
server_name 192.168.1.166;
location ~ ^/music/(\d+)\.mp3$ {
return 200 "/music/$1.mp3";
}
rewrite ^/download/mp3/(\d+)\.mp3$ /music/$1.mp3 redirect;
}
請(qǐng)求:GET http://192.168.1.166:86/download/mp3/001.mp3
,響應(yīng):302 http://192.168.1.166:86/music/001.mp3
。
redirect
與last
的區(qū)別:last
會(huì)使用新的uri直接響應(yīng),而redirect
會(huì)向客戶端返回重定向,如下圖:
配置文件
server {
rewrite_log on;
error_log /usr/local/nginx/logs/error.log notice;
listen 86;
server_name 192.168.1.166;
location ~ ^/music/(\d+)\.mp3$ {
return 200 "/music/$1.mp3";
}
rewrite ^/download/mp3/(\d+)\.mp3$ /music/$1.mp3 permanent;
}
請(qǐng)求:GET http://192.168.1.166:86/download/mp3/001.mp3
,響應(yīng):301 http://192.168.1.166:86/music/001.mp3
permanent
與redirect
區(qū)別:返回狀態(tài)碼不同,permanent返回301永久重定向,redirect返回臨時(shí)重定向302。
閱讀原文:原文鏈接
該文章在 2025/7/1 23:39:32 編輯過