Nginx_Rewrite
1、介紹
- Rewrite根據nginx提供的全局變量或本身設置的變量,結合正則表達式和標誌位實現url重寫和者重定向。
- Rewrite和location相似,均可以實現跳轉,區別是rewrite是在同一域名內更改url,而location是對同類型匹配路徑作控制訪問,或者proxy_pass代理到其餘服務器。
- Rewrite和location執行順序:
- 執行server下的rewrite
- 執行location匹配
- 執行location下的rewrite
2、語法和參數說明
1.rewrite語法格式
rewrite <regex> <replacement> <flag>;
關鍵字 正則表達式 代替的內容 重寫類型
Rewrite:通常都是rewrite
Regex:能夠是字符串或者正則來表示想要匹配的目標URL
Replacement:將正則匹配的內容替換成replacement
Flag:flag標示,重寫類型:
- last:本條規則匹配完成後,繼續向下匹配新的location URI規則;至關於Apache裏德(L)標記,表示完成rewrite,瀏覽器地址欄URL地址不變;通常寫在server和if中;
- break:本條規則匹配完成後,終止匹配,再也不匹配後面的規則,瀏覽器地址欄URL地址不變;通常使用在location中;
- redirect:返回302臨時重定向,瀏覽器地址會顯示跳轉後的URL地址;
- permanent:返回301永久重定向,瀏覽器地址欄會顯示跳轉後的URL地址;
server {
# 訪問 /last.html 的時候,頁面內容重寫到 /index.html 中,並繼續後面的匹配,瀏覽器地址欄URL地址不變
rewrite /last.html /index.html last;
# 訪問 /break.html 的時候,頁面內容重寫到 /index.html 中,並中止後續的匹配,瀏覽器地址欄URL地址不變;
rewrite /break.html /index.html break;
# 訪問 /redirect.html 的時候,頁面直接302定向到 /index.html中,瀏覽器地址URL跳爲index.html
rewrite /redirect.html /index.html redirect;
# 訪問 /permanent.html 的時候,頁面直接301定向到 /index.html中,瀏覽器地址URL跳爲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;
# 把當前域名的請求,跳轉到新域名上,域名變化但路徑不變
rewrite ^/(.*) http://www.jd.com/$1 permanent;
}
二、IF判斷和內置全局環境變量
if (表達式) {
}
#當表達式只是一個變量時,若是值爲空或任何以0開頭的字符串都會當作false直接比較變量和內容時,使用=或!=~正則表達式匹配,~*不區分大小寫的匹配,!~區分大小寫的不匹配
$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相同。
例子:
URL:http://localhost:81/download/stat.php?id=1585378&web_id=1585378
Server_Dir:/var/www/html
$host:localhost
$server_port:81
$request_uri:/download/stat.php?id=1585378&web_id=1585378
$document_uri:/download/stat.php
$document_root:/var/www/html
$request_filename:/var/www/html/download/stat.php
# 若是文件不存在則返回400
if (!-f $request_filename) {
return 400;
}
# 若是host是www.360buy.com,則301到www.jd.com中
if ( $host != "www.jd.com" ){
rewrite ^/(.*)$ https://www.jd.com/$1 permanent;
}
# 若是請求類型是POST則返回405,return不能返回301,302
if ($request_method = POST) {
return 405;
}
# 若是參數中有 a=1 則301到指定域名
if ($args ~ a=1) {
rewrite ^ http://example.com/ permanent;
}
- 文件名及參數重寫
location = /index.html {
# 修改默認值爲
set $name test;
# 若是參數中有 name=xx 則使用該值
if ($args ~* name=(\w+?)(&|$)) {
set $name $1;
}
# permanent 301重定向
rewrite ^ /$name.html permanent;
}
- 隱藏真實目錄
server {
root /var/www/html;
# 用 /html_test 來掩飾 html
location / {
# 使用break拿一旦匹配成功則忽略後續location
rewrite /html_test /html break;
}
# 訪問真實地址直接報沒權限
location /html {
return 403;
}
}
- 禁止指定IP訪問
location / {
if ($remote_addr = 192.168.1.253) {
return 403;
}
}
- 若是請求的文件不存在,則反向代理到localhost 。這裏的break也是中止繼續rewrite
if (!-f $request_filename){
break;
proxy_pass http://127.0.0.1;
}
- 對/images/bla_500x400.jpg文件請求,重寫到/resizer/bla.jpg?width=500&height=400地址,並會繼續嘗試匹配location。
rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;
Proxy_Pass
Proxy_pass反向代理,用的是nginx的Proxy模塊
第一種:
location /proxy/ {
proxy_pass http://127.0.0.1/;
}
代理到URL:http://127.0.0.1/test.html
第二種:
location /proxy/ {
proxy_pass http://127.0.0.1; #少/
}
代理到URL:http://127.0.0.1/proxy/test.html
第三種:
location /proxy/ {
proxy_pass http://127.0.0.1/aaa/;
}
代理到URL:http://127.0.0.1/aaa/test.html
第四種(相對於第三種,最後少一個 / )
location /proxy/ {
proxy_pass http://127.0.0.1/aaa;
}
代理到URL:http://127.0.0.1/aaatest.html
- proxy_set_header Host $host; 做用web服務器上有多個站點時,用該參數header來區分反向代理哪一個域名。好比下邊的代碼舉例。
- proxy_set_header X-Forwarded-For $remote_addr; 做用是後端服務器上的程序獲取訪客真實IP,從該header頭獲取。部分程序須要該功能。
- Proxy_pass配合upstream實現負載均衡
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
upstream core_tomcat {
server 192.168.1.253:80 weight=5 max_fails=3 fail_timeout=30;
server 192.168.1.252:80 weight=1 max_fails=3 fail_timeout=30;
server 192.168.1.251:80 backup;
}
server {
listen 80;
server_name www.jd.com;
location /web {
proxy_pass http://core_tomcat;
proxy_set_header Host $host;
}
}
}
參考文檔:
https://www.jianshu.com/p/10ecc107b5eephp