天天看點

linux nginx 重寫模式,nginx配置url重寫

url重寫是指通過配置conf檔案,以讓網站的url中達到某種狀态時則定向/跳轉到某個規則,比如常見的僞靜态、301重定向、浏覽器定向等

rewrite

文法

在配置檔案的server塊中寫,如:

server {

rewrite 規則 定向路徑 重寫類型;

}

規則:可以是字元串或者正則來表示想比對的目标url

定向路徑:表示比對到規則後要定向的路徑,如果規則裡有正則,則可以使用$index來表示正則裡的捕獲分組

重寫類型:

last :相當于apache裡德(l)标記,表示完成rewrite,浏覽器位址欄url位址不變

break;本條規則比對完成後,終止比對,不再比對後面的規則,浏覽器位址欄url位址不變

redirect:傳回302臨時重定向,浏覽器位址會顯示跳轉後的url位址

permanent:傳回301永久重定向,浏覽器位址欄會顯示跳轉後的url位址

簡單例子

server {

# 通路 /last.html 的時候,頁面内容重寫到 /index.html 中

rewrite /last.html /index.html last;

# 通路 /break.html 的時候,頁面内容重寫到 /index.html 中,并停止後續的比對

rewrite /break.html /index.html break;

# 通路 /redirect.html 的時候,頁面直接302定向到 /index.html中

rewrite /redirect.html /index.html redirect;

# 通路 /permanent.html 的時候,頁面直接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的差別

因為301和302不能簡單的隻傳回狀态碼,還必須有重定向的url,這就是return指令無法傳回301,302的原因了。這裡 last 和 break 差別有點難以了解:

last一般寫在server和if中,而break一般使用在location中

last不終止重寫後的url比對,即新的url會再從server走一遍比對流程,而break終止重寫後的比對

break和last都能組織繼續執行後面的rewrite指令

在location裡一旦傳回break則直接生效并停止後續的比對location

server {

location / {

rewrite /last/ /q.html last;

rewrite /break/ /q.html break;

}

location = /q.html {

return 400;

}

}

通路/last/時重寫到/q.html,然後使用新的uri再比對,正好比對到locatoin = /q.html然後傳回了400

通路/break時重寫到/q.html,由于傳回了break,則直接停止了

if判斷

隻是上面的簡單重寫很多時候滿足不了需求,比如需要判斷當檔案不存在時、當路徑包含xx時等條件,則需要用到if

文法

if (表達式) {

}

當表達式隻是一個變量時,如果值為空或任何以0開頭的字元串都會當做false

直接比較變量和内容時,使用=或!=

~正規表達式比對,~*不區分大小寫的比對,!~區分大小寫的不比對

一些内置的條件判斷:

-f和!-f用來判斷是否存在檔案

-d和!-d用來判斷是否存在目錄

-e和!-e用來判斷是否存在檔案或目錄

-x和!-x用來判斷檔案是否可執行

内置的全局變量

$args :這個變量等于請求行中的參數,同$query_string

$content_length : 請求頭中的content-length字段。

$content_type : 請求頭中的content-type字段。

$document_root : 目前請求在root指令中指定的值。

$host : 請求主機頭字段,否則為伺服器名稱。

$http_user_agent : 用戶端agent資訊

$http_cookie : 用戶端cookie資訊

$limit_rate : 這個變量可以限制連接配接速率。

$request_method : 用戶端請求的動作,通常為get或post。

$remote_addr : 用戶端的ip位址。

$remote_port : 用戶端的端口。

$remote_user : 已經經過auth basic module驗證的使用者名。

$request_filename : 目前請求的檔案路徑,由root或alias指令與uri請求生成。

$scheme : http方法(如http,https)。

$server_protocol : 請求使用的協定,通常是http/1.0或http/1.1。

$server_addr : 伺服器位址,在完成一次系統調用後可以确定這個值。

$server_name : 伺服器名稱。

$server_port : 請求到達伺服器的端口号。

$request_uri : 包含請求參數的原始uri,不包含主機名,如:”/foo/bar.php?arg=baz”。

$uri : 不帶請求參數的目前uri,$uri不包含主機名,如”/foo/bar.html”。

$document_uri : 與$uri相同。

如:

通路連結是:http://localhost:88/test1/test2/test.php

網站路徑是:/var/www/html

$host:localhost

$server_port:88

$request_uri:http://localhost:88/test1/test2/test.php

$document_uri:/test1/test2/test.php

$document_root:/var/www/html

$request_filename:/var/www/html/test1/test2/test.php

例子

# 如果檔案不存在則傳回400

if (!-f $request_filename) {

return 400;

}

# 如果host不是xuexb.com,則301到xuexb.com中

if ( $host != "xuexb.com" ){

rewrite ^/(.*)$ https://xuexb.com/$1 permanent;

}

# 如果請求類型不是post則傳回405

if ($request_method = post) {

return 405;

}

# 如果參數中有 a=1 則301到指定域名

if ($args ~ a=1) {

rewrite ^ http://example.com/ permanent;

}

在某種場景下可結合location規則來使用,如:

# 通路 /test.html 時

location = /test.html {

# 預設值為xiaowu

set $name xiaowu;

# 如果參數中有 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

文法

在server塊中使用,如:

server {

location 表達式 {

}

}

location表達式類型

如果直接寫一個路徑,則比對該路徑下的

~ 表示執行一個正則比對,區分大小寫

~* 表示執行一個正則比對,不區分大小寫

^~ 表示普通字元比對。使用字首比對。如果比對成功,則不再比對其他location。

= 進行普通字元精确比對。也就是完全比對。

優先級

等号類型(=)的優先級最高。一旦比對成功,則不再查找其他比對項。

^~類型表達式。一旦比對成功,則不再查找其他比對項。

正規表達式類型(~ ~*)的優先級次之。如果有多個location的正則能比對的話,則使用正規表達式最長的那個。

正常字元串比對類型。按字首比對。

例子 - 假位址掩飾真位址

server {

# 用 xxoo_admin 來掩飾 admin

location / {

# 使用break拿一旦比對成功則忽略後續location

rewrite /xxoo_admin /admin break;

}

# 通路真實位址直接報沒權限

location /admin {

return 403;

}

}

參數連結