Nginx教程(4)-Rewrite

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不滿足,會繼續執行

附錄

內置的全局變量
argsargs :這個變量等於請求行中的參數,同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”。
uriURIuri : 不帶請求參數的當前 URI,uri 不包含主機名,如”/foo/bar.html”。
documenturidocument_uri : 與uri 相同。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章