proxy_pass 只能將請求進行轉發,而rewrite的功能就多嘍,如
- 可以調整用戶瀏覽的 URL,看起來更規範,合乎開發及產品人員的需求。
- 爲了讓搜索引擎搜錄網站內容及用戶體驗更好,企業會將動態 URL 地址僞裝成靜態地址提供服務。
- 網址換新域名後,讓舊的訪問跳轉到新的域名上。例如,訪問京東的 360buy.com 會跳轉到 jd.com
- 根據特殊變量、目錄、客戶端的信息進行 URL 調整等
rewrite語法:
server {
rewrite 規則 定向路徑 重寫類型;
}
- 規則:可以是字符串或者正則來表示想匹配的目標 url
- 定向路徑:表示匹配到規則後要定向的路徑,如果規則裏有正則,則可以使用$index 來表示正則裏的捕獲分組
- 重寫類型:last、break、redirect、permanent
server {
listen 80;
server_name localhost;
rewrite /break.html /index.html break;
}
rewrite可以直接作用於server中,訪問 /break.html 的時候,頁面內容重寫到 /index.html 中
重寫類型:
- last :表示完成 rewrite,瀏覽器地址欄 URL 地址不變
- break;本條規則匹配完成後,終止匹配,不再匹配後面的規則,瀏覽器地址欄 URL
地址不變 - redirect:返回 302 臨時重定向,瀏覽器地址會顯示跳轉後的 URL 地址
- permanent:返回 301 永久重定向,瀏覽器地址欄會顯示跳轉後的 URL 地址
last和break的區別:
- last 一般寫在 server 和 if 中,而 break 一般使用在 location 中
- last 不終止重寫後的 url 匹配,即新的 url 會再從 server 走一遍匹配流程,而 break 終止重寫後的匹配
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,則直接停止了
rewrite 可以寫在server中也可以寫在location中,先判斷server中的,然後再判斷location中的。
if判斷
在Nginx中可以使用if做一些簡單的邏輯判斷
if (表達式) {
}
表達式判斷:
1、正則表達式匹配:
==:等值比較;
~:與指定正則表達式模式匹配時返回“真”,判斷匹配與否時區分字符大小寫;
~:與指定正則表達式模式匹配時返回“真”,判斷匹配與否時不區分字符大小寫;
!~:與指定正則表達式模式不匹配時返回“真”,判斷匹配與否時區分字符大小寫;
!~:與指定正則表達式模式不匹配時返回“真”,判斷匹配與否時不區分字符大小寫;
2、文件及目錄匹配判斷:
-f, !-f:判斷指定的路徑是否爲存在且爲文件;
-d, !-d:判斷指定的路徑是否爲存在且爲目錄;
-e, !-e:判斷指定的路徑是否存在,文件或目錄均可;
-x, !-x:判斷指定路徑的文件是否存在且可執行;
3、部分正則表達式可以在圓括號內"()",其值可以通過後面的變量$1到$9來訪問:
rewrite ^/b/(.).html /play.php?video=$1 last;#其中$1就表示引用前面匹配的(.)裏面的內容。
Nginx可以通過內置變量獲取url信息,如:
問鏈接是:http://localhost:8080/test1/test2/test.jsp
$host:localhost
$server_port:8080
$request_uri:http://localhost:8080/test1/test2/test.jsp
$document_uri:/test1/test2/test.jsp
更內置變量見附件
server {
# 如果 host 不是 a.test.com,則 301 到 a.test.com 中
if ( $host != "a.test.com" ){
rewrite ^/(.*)$ https://a.test.com/$1 permanent;
}
# 如果請求類型不是 POST 則返回 405
if ($request_method = POST) {
return 405;
}
location / {
# 自定義變量
set $flag 0;
if ($host != "a.test.com" ) {
set $flag "${flag}1";
}
if ($flag = "01") {
return 500;
}
}
}
if不僅可以作用於server中,也可以作用於location中
server {
location / {
if ($host = "a.test.com"){
rewrite ^/(.*)$ http://b.test.com/$1 permanent;
}
# $1 表示正則表達式(.*).html$匹配的結果(.*)
rewrite ^/shop/list/cat-(.*).html$ /ecps-portal/listcat?catId=$1 break;
rewrite ^/shop/(.*)$ /ecps-portal/shop/$1.jsp last;
# 請求將會轉發到 b.test.com
proxy_pass http://b.test.com;
}
}
如果if不滿足,會繼續執行
附錄
內置的全局變量
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 不包含主機名,如”/foo/bar.html”。
uri 相同。