server {
rewrite 規(guī)則 定向路徑 重寫類型;
}
規(guī)則:可以是字符串或者正則來表示想匹配的目標(biāo)url
定向路徑:表示匹配到規(guī)則后要定向的路徑宇攻,如果規(guī)則里有正則庸队,則可以使用$index來表示正則里的捕獲分組
重寫類型:
last :相當(dāng)于Apache里德(L)標(biāo)記,表示完成rewrite,瀏覽器地址欄URL地址不變
break;本條規(guī)則匹配完成后,終止匹配稿辙,不再匹配后面的規(guī)則,瀏覽器地址欄URL地址不變
redirect:返回302臨時(shí)重定向气忠,瀏覽器地址會(huì)顯示跳轉(zhuǎn)后的URL地址
permanent:返回301永久重定向邓深,瀏覽器地址欄會(huì)顯示跳轉(zhuǎn)后的URL地址
簡(jiǎn)單例子
server {
# 訪問 /last.html 的時(shí)候,頁(yè)面內(nèi)容重寫到 /index.html 中
rewrite /last.html /index.html last;
# 訪問 /break.html 的時(shí)候笔刹,頁(yè)面內(nèi)容重寫到 /index.html 中芥备,并停止后續(xù)的匹配
rewrite /break.html /index.html break;
# 訪問 /redirect.html 的時(shí)候,頁(yè)面直接302定向到 /index.html中
rewrite /redirect.html /index.html redirect;
# 訪問 /permanent.html 的時(shí)候舌菜,頁(yè)面直接301定向到 /index.html中
rewrite /permanent.html /index.html permanent;
# 把 /html/*.html => /post/*.html 萌壳,301定向
rewrite ^/html/(.+?).html$ /post/$1.html permanent;
# 把 /search/key => /search.html?keyword=key
rewrite ^/search\/([^\/]+?)(\/|$) /search.html?keyword=$1 permanent;
}
last和break的區(qū)別
因?yàn)?01和302不能簡(jiǎn)單的只返回狀態(tài)碼,還必須有重定向的URL,這就是return指令無法返回301,302的原因了袱瓮。這里 last 和 break 區(qū)別有點(diǎn)難以理解:
last一般寫在server和if中缤骨,而break一般使用在location中
last不終止重寫后的url匹配,即新的url會(huì)再?gòu)膕erver走一遍匹配流程尺借,而break終止重寫后的匹配
break和last都能組織繼續(xù)執(zhí)行后面的rewrite指令
在location里一旦返回break則直接生效并停止后續(xù)的匹配location
server {
location / {
rewrite /last/ /q.html last;
rewrite /break/ /q.html break;
}
location = /q.html {
return 400;
}
}
訪問/last/時(shí)重寫到/q.html绊起,然后使用新的uri再匹配,正好匹配到locatoin = /q.html然后返回了400
訪問/break時(shí)重寫到/q.html燎斩,由于返回了break虱歪,則直接停止了
if判斷
只是上面的簡(jiǎn)單重寫很多時(shí)候滿足不了需求,比如需要判斷當(dāng)文件不存在時(shí)栅表、當(dāng)路徑包含xx時(shí)等條件笋鄙,則需要用到if
語(yǔ)法
if (表達(dá)式) {
}
當(dāng)表達(dá)式只是一個(gè)變量時(shí),如果值為空或任何以0開頭的字符串都會(huì)當(dāng)做false
直接比較變量和內(nèi)容時(shí)怪瓶,使用=或!=
正則表達(dá)式匹配萧落,*不區(qū)分大小寫的匹配,!~區(qū)分大小寫的不匹配
一些內(nèi)置的條件判斷:
-f和!-f用來判斷是否存在文件
-d和!-d用來判斷是否存在目錄
-e和!-e用來判斷是否存在文件或目錄
-x和!-x用來判斷文件是否可執(zhí)行
內(nèi)置的全局變量
query_string
content_type : 請(qǐng)求頭中的Content-Type字段。
host : 請(qǐng)求主機(jī)頭字段宣增,否則為服務(wù)器名稱。
http_cookie : 客戶端cookie信息
request_method : 客戶端請(qǐng)求的動(dòng)作,通常為GET或POST帖旨。
remote_port : 客戶端的端口。
request_filename : 當(dāng)前請(qǐng)求的文件路徑落竹,由root或alias指令與URI請(qǐng)求生成。
server_protocol : 請(qǐng)求使用的協(xié)議,通常是HTTP/1.0或HTTP/1.1蟹地。
server_name : 服務(wù)器名稱怪与。
request_uri : 包含請(qǐng)求參數(shù)的原始URI,不包含主機(jī)名,如:”/foo/bar.php?arg=baz”遍愿。
uri不包含主機(jī)名,如”/foo/bar.html”沼填。
uri相同桅咆。
如:
訪問鏈接是:http://localhost:88/test1/test2/test.php
網(wǎng)站路徑是:/var/www/html
server_port:88
document_uri:/test1/test2/test.php
request_filename:/var/www/html/test1/test2/test.php
例子
如果文件不存在則返回400
if (!-f $request_filename) {
return 400;
}
如果host不是xuexb.com,則301到xuexb.com中
if ( https://xuexb.com/$1 permanent;
}
如果請(qǐng)求類型不是POST則返回405
if ($request_method = POST) {
return 405;
}
如果參數(shù)中有 a=1 則301到指定域名
if ($args ~ a=1) {
rewrite ^ http://example.com/ permanent;
}
在某種場(chǎng)景下可結(jié)合location規(guī)則來使用坞笙,如:
訪問 /test.html 時(shí)
location = /test.html {
# 默認(rèn)值為xiaowu
set $name xiaowu;
# 如果參數(shù)中有 name=xx 則使用該值
if ($args ~* name=(\w+?)(&|$)) {
set $name $1;
}
# 301
rewrite ^ /$name.html permanent;
}
上面表示:
/test.html => /xiaowu.html
/test.html?name=ok => /ok.html?name=ok
location
語(yǔ)法
在server塊中使用岩饼,如:
server {
location 表達(dá)式 {
}
}
location表達(dá)式類型
如果直接寫一個(gè)路徑,則匹配該路徑下的
~ 表示執(zhí)行一個(gè)正則匹配羞海,區(qū)分大小寫
~* 表示執(zhí)行一個(gè)正則匹配忌愚,不區(qū)分大小寫
^~ 表示普通字符匹配。使用前綴匹配却邓。如果匹配成功硕糊,則不再匹配其他location。
= 進(jìn)行普通字符精確匹配腊徙。也就是完全匹配简十。
優(yōu)先級(jí)
等號(hào)類型(=)的優(yōu)先級(jí)最高。一旦匹配成功撬腾,則不再查找其他匹配項(xiàng)螟蝙。
^~類型表達(dá)式。一旦匹配成功民傻,則不再查找其他匹配項(xiàng)胰默。
正則表達(dá)式類型(~ ~*)的優(yōu)先級(jí)次之。如果有多個(gè)location的正則能匹配的話漓踢,則使用正則表達(dá)式最長(zhǎng)的那個(gè)牵署。
常規(guī)字符串匹配類型。按前綴匹配喧半。
例子 - 假地址掩飾真地址
server {
# 用 xxoo_admin 來掩飾 admin
location / {
# 使用break拿一旦匹配成功則忽略后續(xù)location
rewrite /xxoo_admin /admin break;
}
# 訪問真實(shí)地址直接報(bào)沒權(quán)限
location /admin {
return 403;
}
}