Nginx rewrite 詳解
本篇主要介紹 nginx 的 rewrite 重定向這個功能進行 詳解介紹, 以及介紹它的使用場景
1. rewrite 基本介紹
rewrite是實現URL重寫的關鍵指令,根據regex (正規表示式)部分內容,重定向到replacement,結尾是flag標記。
基本語法:
rewrite <regex> <replacement> [flag];
關鍵字 正則 替代內容 flag標記
- regex: 正規表示式語句進行規則匹配
- replacement: 將正則匹配的內容替換成replacement
- flag: last | break | redirect | permanent
- last : 本條規則匹配完成後,繼續向下匹配新的location URI規則
- break: 本條規則匹配完成即終止,不再匹配後面的任何規則
- redirect : 回302臨時重定向,瀏覽器地址會顯示跳轉後的URL地址 (防爬蟲)
- permanent : 返回301永久重定向,瀏覽器位址列會顯示跳轉後的URL地址
rewrite 使用位置
- server : 在server中針對所有的請求
- location : 在 location 中則針對 單個匹配路徑的
- If
2. server 中使用 rewrite
直接在server中使用 rewrite , 它會被先執行 優先於 location 中的
2.1 rewrite 外部站點
rewrite 到外部站點 是指 replacement 部分 是一個完整的 帶 http/https 的 外部路徑 ,它的特點是 瀏覽器會再次請求這個新的站點 所以瀏覽器上的地址一定會發生變化 不受 flag 引數影響
全部攔截 ^/(.*)$
下面的配置是 所有的請求都轉發了 https://www.askajohnny.com
...
server {
listen 80;
server_name www.testfront.com;
#由於是外部站點帶http/s 的 所以不受flag 影響 break last .. 都會進行跳轉並且變更瀏覽器url
rewrite ^/(.*)$ https://www.askajohnny.com break;
location / {
root html;
index index.html;
}
}
...
部分匹配
server {
listen 80;
server_name www.testfront.com;
#只有當字尾是 數字.html 的時候才會轉發到 https://www.askajohnny.com
rewrite ^/([0-9]+).html$ https://www.askajohnny.com break;
#其他的請求會走到這個location中
location / {
root html;
index index.html;
}
}
經過測試可以發現 直接跳轉過去 並且 瀏覽器中的地址也直接變成了 https://www.askajohnny.com , 待會我們再詳細討論 什麼時候會變化這個地址
比如在我的 部落格網站中 我把http 的請求全部rewrite 轉發到 https 上了
, 因為我的QQ登入當時填寫的回撥是 http,又因為QQ互聯的稽核太麻煩 太慢 所以乾脆就這樣配置
2.2 rewrite 到內部站
點
rewrite 到內部站點是指 replacement 不帶http/https 而是內部的另外一個路徑 , 相當於訪問隱藏起來的這個 內部路徑,
只有這種內部站點跳轉的時候 瀏覽器才有可能不變地址 要看 rewite flag 引數了 last 和 break 都不會變的, 只有 redirect 和 permanent
server {
listen 80;
server_name www.testfront.com;
#只有當字尾是 數字.html 的時候才會轉發到 https://www.askajohnny.com
rewrite ^/([0-9]+).html$ /my.gif break;
#其他的請求會走到這個location中
location / {
root html;
index index.html;
}
# 上面的rewrite 會被路由到這裡 並且瀏覽器是不會感知到的
location /my.gif {
root /www/static/;
}
}
經過測試 當訪問 www.testfront.com/222.html 的時候
- flag = last 瀏覽器不會變化 隱藏了 後端 /my.gif 地址
- flag = break 瀏覽器不會變化 隱藏了 後端 /my.gif 地址
- flag = redirect 和 permanent 瀏覽器變化了URL 變更狀態碼 302和 301
3. location 中使用rewrite
location 中也可以使用 rewrite 意思是隻有匹配到 這個location 後才經過 rewrite 的正則透過後 再跳轉
和上面一樣 也分為 rewirte 的 replacement 是否包含http和https 外部站點
希望是如果 訪問的字尾 是 數字.html 則 返回 my.gif 圖 ,其他的都代理到 http://www.testbackend.com
server {
listen 80;
server_name www.testfront.com;
#rewrite ^/([0-9]+).html$ /my.gif last;
location /my.gif {
root /www/static/;
}
location / {
rewrite ^/([0-9]+).html$ /my.gif break;
proxy_pass http://www.testbackend.com;
}
}
經過測試 只有訪問www.testfront.com/數字.html 的時候 才能獲取到 my.gif 檔案
4. 使用場景模擬
4.1 基於域名跳轉
比如現在你所在的公司 網站域名是 www.testfront.com 現在需要使用新的域名 www.newtestfront.com 替代, 但是舊的域名不能作廢, 需要讓舊的域名跳轉到新的域名上 , 並且保持後面引數不變
模擬原本配置
server {
listen 80;
server_name www.testfront.com;
location / {
proxy_pass http://www.testbackend.com;
}
}
新配置,使用rewrite 操作 當訪問老的域名 www.testfront.com 跳轉到 新的 www.newtestfront.com
server {
listen 80;
server_name www.testfront.com ...;
location / {
# $host 是可以拿到訪問的主機名
if ( $host = 'www.testfront.com' ) {
rewrite ^/(.*)$ http://www.newtestfront.com/$1 permanent;
}
proxy_pass http://www.testbackend.com;
}
location ^~ /static/ {
root /www/static;
}
}
server {
listen 80;
server_name www.newtestfront.com;
location / {
# 這裡可以改成 新域名的 新後端代理的服務, 依據實際情況
proxy_pass http://www.testbackend.com;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
4.2 基於客戶端 IP 訪問跳轉
今天公司業務新版本上線,要求所有 IP 訪問任何內容都顯示一個固定維護頁面,只有公司IP:192.168.200.100訪問正常。
server {
listen 80;
server_name www.testfront.com ...;
# 先設定 rewrite變數為true
set $rewrite true;
# 當客戶端ip 是172.16.225.1 的時候 才不 rewrite
if ( $remote_addr = "172.16.225.1" ) {
set $rewrite = false;
}
if ( $rewirte = true) {
# 將rewrite到 維護介面 weihu.html
rewrite (.+) /weihu.html;
}
location /weihu.html {
# 如果要使用 echo 則需要載入 echo-nginx-module 才行
echo "remote_addr: $remote_addr";
root /www/weihu/;
}
location / {
# 如果要使用 echo 則需要載入 echo-nginx-module 才行
echo "remote_addr: $remote_addr";
# 如果是 remote_addr 是特定的ip 則直接正常訪問後臺
proxy_pass http://www.testbackend.com;
}
}
此時如果是 172.16.225.1 訪問就可以到 後端, 如果是其他的客戶端ip 訪問就只能到 weihu.html 頁面
注意 下面是 echo-nginx-module 模組需要單獨下載載入 如果你需要除錯的話
git clone https://gitee.com/yaowenqiang/echo-nginx-module.git
總結
本篇主要介紹了 nginx 中 rewrite 的基本概念 以及基本的使用方式 ,rewrite 可以出現在 server , location , if 中
並且介紹了 什麼時候才會變化瀏覽器URL , 以及介紹了2個模擬場景
-
rewirte 內部站點
當rewrite 到內部站點的時候 會根據 flag 引數 last break不變 redirect permanent 變化
-
rewrite 外部站點 帶http/https 等
當rewrite 外部站點 不管flag 引數 瀏覽器URL都會進行變化 相當於瀏覽器進行了 二次請求了
歡迎大家訪問 個人部落格 Johnny小屋
歡迎關注個人公眾號