Nginx實現Rewrite地址重寫


rewrite介紹

# 什么叫做rewite重寫
Rewrite主要實現url地址重寫,以及重定向,就是把傳入web的請求重定向到其他url的過程。將瀏覽器,發送到服務器的請求(url),根據規則重寫,返回給用戶
到底要干什么:就是修改url

# 為什么要修改url:
· 為了安全,為了提高用戶的體驗

# rewrite使用場景
1、地址跳轉,用戶訪問www.drz.com這個URL是,將其定向至一個新的域名mobile.drz.com
2、協議跳轉,用戶通過http協議請求網站時,將其重新跳轉至https協議方式
3、偽靜態,將動態頁面顯示為靜態頁面方式的一種技術,便於搜索引擎的錄入,同時建上動態URL地址對外暴露過多的參數,提升更高的安全性。
4、搜索引擎,SEO優化依賴於url路徑,好記的url便於智齒搜索引擎錄入

# rewrite配置示例:
句法:Syntax:  rewrite regex replacement [flag]
· rewrite:為關鍵字
· regex:正則表達式
· URL:需要替代內容
· [flag]:標記位
默認:Default: --
語境:Context: server,location,if

#用於切換維護頁面場景
rewrite ^(.*)$ /page/maintain.html break;

# Nginx Rewrite的location正則表達式
參考:https://blog.51cto.com/renzhiyuan/1898091

# 注意:
ruturn也可以作為地址重寫使用,但僅限於301和302的永久重定向和臨時重定向
· 例:(將匹配信息臨時重定向到新的URL)
   return 302 https://blog.driverzeng.com;

Rerite標記Flag

  • rewrite指令根據表達式來重定向URL,或者修改字符串,可以應用於server,location,if環境下,每行rewrite指令最后跟一個flag標記,支持的flag標記有如下表格所示:
  • rewrite ^(.*)$ /page/maintain.html break;(語法格式參考)
flag 作用
last 本條規則匹配完成后,停止匹配,不再匹配后面的規則,但會改變URL路徑重新匹配
break 本條規則匹配完成后,停止匹配,不再匹配后面的規則
redirect 返回302臨時重定向,地址欄會顯示跳轉后的地址。等於 return 302
permanent 返回301永久重定向,地址欄會顯示跳轉后的地址,但優先有瀏覽器緩存。等於 return 301
  • break請求與last區別(不常用)

break 只要匹配到規則,則會去本地配置路徑的目錄中尋找請求的文件;
而last只要匹配到規則,會對其所在的server(...)標簽重新發起請求。

# · break與last示例:
[root@web01 conf.d]# cat rewrite.conf 
server {
        listen 80;
        server_name rewrite.drz.com;
        root /code;

        location ~ ^/break {
                rewrite ^/break /test/ break;
        }
        location ~ ^/last {
                rewrite ^/last /test/ last;
        }
        location /test/ {
                default_type application/json;
                return 200 "ok";
        }
}
# · break與last總結:(如上示例總結)
break請求:(一般使用在location中)
1、請求rewrite.drz.com/break
2、首先:會去查找本地的/code/test/index.html;
3、如果找到了,則返回/code/test/index.html的內容;
4、如果沒找到該目錄則報錯404,如果找到該目錄沒找到對應的文件則403

# last請求:(位於server和if中)
1、請求rewrite.drz.com/last
2、首先:會去查找本地的/code/test/index.html;
3、如果找到了,則返回/code/test/index.html的內容;
4、如果沒找到,會對當前server重新的發起一次請求,rewrite.drz.com/test/
5、如果有location匹配上,則直接返回該location的內容。
4、如果也沒有location匹配,再返回404;

· 所以,在訪問/break和/last請求時,雖然對應的請求目錄/test都是不存在的,理論上都應該返回404,但是實際上請求/last的時候,是會有后面location所匹配到的結果返回的,原因在於此。

  • redirect與permanent區別(常用為redirect)
# · redirect與permanent示例:
[root@web01 conf.d]# cat rewrite.conf 
server {
        listen 80;
        server_name rewrite.drz.com;
        root /code;

        location /test {
                rewrite ^(.*)$  https://blog.driverzeng.com redirect;		# redirect示例
                #rewrite ^(.*)$  https://blog.driverzeng.com permanent;		# permanent示例
                #return 301 https://blog.driverzeng.com;			# 忽略,但也可用return方式
                #return 302 https://blog.driverzeng.com;			
        }
}

# · redirect與permanent總結(如上示例可得)
redirect: 每次請求都會詢問服務器,如果當服務器不可用時,則會跳轉失敗。
permanent: 第一次請求會詢問,瀏覽器會記錄跳轉的地址,第二次則不再詢問服務器,直接通過瀏覽器緩存的地址跳轉。

Rewrite規則實踐(大部分需開發實現功能)

案例一:

  • 用戶訪問/abc/1.html實際上真實訪問的是/ccc/bbb/2.html
#http://www.drz.com/abc/1.html  ==>  http://www.drz.com/ccc/bbb/2.html

#1.准備真實訪問路徑
[root@web03 ~]# mkdir /code/ccc/bbb -p
[root@web03 ~]# echo "ccc_bbb_2" > /code/ccc/bbb/2.html

#2.Nginx跳轉配置
[root@web03 ~]# cd /etc/nginx/conf.d/
[root@web03 conf.d]# cat ccbb.conf 
server {
        listen 80;

        location / {
                root /code;
                index index.html;
        }
        location /abc {
                rewrite (.*) /ccc/bbb/2.html redirect;
                #return 302 /ccc/bbb/2.html;
        }
}

#3.重啟Nginx服務
[root@web03 conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web03 conf.d]# nginx -s reload

案例二:

  • 用戶訪問/2018/ccc/2.html實際上真實訪問的是/2014/ccc/bbb/2.html
##http://www.drz.com/2018/ccc/2.html  ==>  http://www.drz.com/2014/ccc/bbb/2.html

#1.准備真是的訪問路徑
[root@web03 conf.c]# mkdir /code/2014/ccc/bbb -p 
[root@web03 conf.c]# echo "2014_ccc_bbb_2" > /code/2014/ccc/bbb/2.html

#2.Nginx跳轉配置
[root@web03 conf.d]# cat ccbb.conf 
server {
        listen 80;

        location / {
                root /code;
                index index.html;
        }
        location /2018 {
                rewrite ^/2018/(.*)$ /2014/$1 redirect;
        }
}

#3.重啟nginx服務
[root@web03 conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web03 conf.d]# nginx -s reload

案例三:

#1.Nginx跳轉配置
[root@web03 conf.d]# cat test.conf 
server {
        listen 80;

        location /test {
                rewrite (.*) https://blog.driverzeng.com redirect;
        }
}

#2.重啟nginx服務
[root@web03 conf.d]# nginx -s reload

案例四:

  • 用戶訪問couese-11-22-33.html實際上真實訪問的是/course/11/22/33/course_33.html
#http://www.drz.com/couese-11-22-33.html  ==>  http://www.drz.com/course/11/22/33/course_33.html

#1.准備真是的訪問路徑
[root@web03 ~]# mkdir /code/course/11/22/33 -p
[root@web03 ~]# echo "curl docs.etiantian.org" > /code/course/11/22/33/course_33.html

#2.Nginx跳轉配置
[root@web03 conf.d]# cat test.conf 
server {
        listen 80;
        root /code;
        index index.html;
        location / {
                #靈活配法
                rewrite ^/course-(.*)-(.*)-(.*).html$ /course/$1/$2/$3/course_$3.html redirect;
                #固定配法
                #rewrite ^/course-(.*) /course/11/22/33/course_33.html redirect;
        }
}

#3.重啟nginx服務
[root@web03 conf.d]# nginx -s reload

案例五

  • http請求跳轉到https
server {
        listen 80;
        server_name www.dirverzeng.com;
        rewrite ^(.*) https://$server_name$1 redirect;
        #return 302 https://$server_name$request_uri;
}       

server {
        listen 443;
        server_name blog.driverzeng.com;
        ssl on;
}

如何開啟rewrite日志

# 在寫rewrite規則之前,我們需要開啟rewrite日志對規則的匹配進行調試。
[root@web01 code]# vim /etc/nginx/nginx.conf
/var/log/nginx/error.log notice;

http{
    rewrite_log on;
}

Rewrite規則補充

  • Rewrite匹配優先級
1.先執行server塊的rewrite指令
2.其次執行location匹配規則
3.最后執行location中的rewrite

  • Rewrite與Nginx全局變量

Rewrite在匹配過程中,會用到一些Nginx全局變量

# $server_name    		當前用戶請求的域名

server {
        listen 80;
        server_name test.drz.com;
        rewrite ^(.*)$ https://$server_name$1;
}

# $request_filename 請求的文件路徑名(帶網站的主目錄/code/images/test.jpg)
# $request_uri 當前請求的文件路徑(不帶網站的主目錄/inages/test.jpg)

大多數用於http協議轉https協議
server {
        listen 80;
        server_name php.drz.com;
        return 302 https://$server_name$request_uri;
}

# $scheme 用的協議,比如http或者https
  • 如何更加規范書寫rewrite規則
server {
        listen 80;
        server_name www.drz.com drz.com;
        if ($http_host = drz.com){
            rewrite (.*) http://www.drz.com$1;
        }
}

#推薦書寫格式
server {
        listen 80;
        server_name drz.com;
        rewrite ^ http://www.drz.com$request_uri;
}
server {
        listen 80;
        server_name www.drz.com;
}

實戰演示

Rewrite實現頁面跳轉:

要求:

背景:現在我有一個網站,www.linux.com

www.linux.com訪**問主頁面**

friend.linux.com訪**問交友頁面**

blog.linux.com訪問博客頁面

download.linux.com訪問博客頁面



在nginx上部署三套代碼

使用rewrite和return兩種方式完成以下需求 

1、通過www.linux.com/download訪**問到下載頁面**

2、通過www.linux.com/friends訪問到**交友頁面**

3、通過www.linux.com/blog訪問到博客頁面

環境准備

主機名 外網ip 內網ip 角色
web01 10.0.0.7 172.16.1.7 web服務器

操作流程

nginx安裝及配置
# 1.nginx安裝
[root@web01 ~]# yum install -y nginx

# 2.書寫配置文件
[root@web01 ~]# !vim
vim /etc/nginx/conf.d/all.conf +18

server {
        listen 80;
        server_name www.linux.com;
        charset utf-8,gbk;

        location / {
        root /code/page;
        index index.html;
        }

        location /download {
                rewrite (.*) http://download.linux.com redirect;
        }

        location /friends {
                rewrite (.*) http://friend.linux.com redirect;
        }
        location /blog {
                rewrite (.*) http://blog.linux.com redirect;

       # 另外有一種簡單方式,可替代如上三種,需使用正則:
           location ~ /(download|blog|friends) {				 # 直接匹配三種
           rewrite ^/(.*)$ http://$1.linux.com redirect;	                 # 正則匹配根后面用戶輸入內容,$1表示引用(.*)
       # 或者使用下面方式,302臨時跳轉,變量為用戶輸入uri信息
                return 302 http://$request_uri.linux.com;                        # ruturn和rewrite方式取其一即可
        }
}

server {
        listen 80;
        server_name download.linux.com;
        root /code/download;
        index down.html;
}

server {
        listen 80;
        server_name friend.linux.com;
        root /code/friend;
        index friend.html;
}
server {
        listen 80;
        server_name blog.linux.com;
        root /code/blog;
        index blog.html;
}

# 3.根據配置文件創建對應目錄
[root@web01 /]# mkdir /code/{blog,download,friend,page}

# 4.將壓縮包上傳到對應目錄(.html結尾必須為站點目錄下)
[root@web01 /]# ll /code/page/
total 204
-rw-r--r-- 1 root root 95014 Jun  2 14:59 1.b8bb4e9b.jpeg
drwxr-xr-x 2 root root     6 Jun  2 23:57 dist
-rw-r--r-- 1 root root   735 Jun  2 14:59 index.html
-rw-r--r-- 1 root root  1584 Jun  2 14:59 style.7dd7c9fb.css
-rw-r--r-- 1 root root  2341 Jun  2 14:59 style.7dd7c9fb.css.map

[root@web01 /]# ll /code/friend/
total 108
drwxr-xr-x 2 root root     6 Jun  3 00:18 friend
-rw-r--r-- 1 root root  1093 Jun  2 15:05 friend.html

[root@web01 /]# ll /code/blog/
total 8
drwxr-xr-x 2 root root   6 Jun  3 00:19 blog
-rw-r--r-- 1 root root 250 Jun  2 15:08 blog.html

[root@web01 /]# ll /code/download/
total 8
-rw-r--r-- 1 root root 255 Jun  2 15:01 down.html

# 4.重啟服務
[root@web01 /]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web01 /]# systemctl start nginx

# 5.windows配置域名(需要一對多)
10.0.0.7 www.linux.com	download.linux.com blog.linux.com friend.linux.com
  • 頁面測試www.linux.com


Rewrite實現偽靜態

要求

搭建discuz,從頁面中復制rewrite,插入到配置文件,實現偽靜態

環境准備

主機名 外網ip 內網ip 角色
web01 10.0.0.7 172.16.1.7 web服務器、php服務器
db01 10.0.0.51 172.16.1.51 數據庫服務器

操作流程

1.web服務器安裝及配置
# 1.安裝nginx
[root@web01 ~]# yum install -y nginx

# 2.安裝php
[root@web01 /tmp]# yum localinstall -y php*

# 3.將php用戶統一為nginx用戶
[root@web01 ~]# vim /etc/php-fpm.d/www.conf 
user = nginx
group = nginx

# 4.書寫配置文件
[root@web01 ~]# vim /etc/nginx/conf.d/www.dis.conf

server {
        listen 80;
        server_name www.dis.com;
        root /code/dis/upload;
        index index.php index.html;

        location ~ \.php$ {
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include /etc/nginx/fastcgi_params;

        }
}

# 5.根據配置文件創建對應目錄,並將代碼上傳至站點目錄中,並對站點目錄授權
[root@web01 ~]# mkdir /code/dis
[root@web01 ~]# wget http://test.driverzeng.com/Nginx_Code/Discuz_X3.3_SC_GBK.zip
[root@web01 dis]# ll
total 10584
-rw-r--r--  1 root root 10829853 Aug 23  2019 Discuz_X3.3_SC_GBK.zip
drwxr-xr-x  2 root root      102 Jul 27  2017 readme
drwxr-xr-x 12 root root     4096 Jul 27  2017 upload
drwxr-xr-x  4 root root       72 Jul 27  2017 utility
[root@web01 dis]# chown -R nginx.nginx /code

# 6.啟動服務
[root@web01 dis]# systemctl restart nginx
[root@web01 dis]# systemctl restart php-fpm

# 7.域名解析,瀏覽器訪問

2.數據庫創建
# 1.安裝數據庫
[root@db01 ~]# yum install -y mariadb-server

# 2.啟動數據庫並連接
[root@db01 ~]# systemctl start mariadb
[root@db01 ~]# mysql -uroot -p123

# 3.創建連接數據庫用戶及數據庫
MariaDB [(none)]> create database dis;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> grant all on *.* to dis_user@'%' identified by '123';
Query OK, 0 rows affected (0.00 sec)

# 4.繼續頁面配置

  • 登錄頁面

  • 發帖查看URL為動態請求

  • 不需要點擊提交,直接查看rewrite規則

  • 復制rewrite

  • 將復制信息插入到配置文件中

  • 檢測配置文件並重啟

  • 結果

附:-手機電腦訪問頁面自動跳轉

要求

根據不同客戶端用戶識別,將安卓用戶請求發送到一個頁面,iphone用戶請求發送到一個頁面,將pc端用戶發送到一個頁面。實現將客戶端請求分類處理。

環境准備

主機名 主機角色 外網IP 內網IP 提供端口
lb01 負載均衡 10.0.0.5 172.16.1.5 80
web01 提供Android頁面 172.16.1.7 9090
web01 提供Iphone頁面 172.16.1.7 9091
web01 提供pc頁面 172.16.1.7 9092

操作流程

1.網頁搭建

# 1.nginx安裝
[root@web01 ~]# yum install -y nginx

# 2.添加配置文件
[root@web01 ~]# vim /etc/nginx/conf.d/all_web.conf

server {
        listen 9090;
        root /code/android;
        index index.html;
}

server {
        listen 9091;
        root /code/ios;
        index index.html;
}

server {
        listen 9092;
        root /code/pc;
        index index.html;
}

# 3.根據配置文件創建對應目錄及頁面
[root@web01 ~]# mkdir /code/{android,ios,pc} -p
[root@web01 ~]# echo android > /code/android/index.html
[root@web01 ~]# echo ios > /code/ios/index.html
[root@web01 ~]# echo pc > /code/pc/index.html

# 4.服務啟動
[root@web01 ~]# systemctl start nginx

2.代理服務器配置

# 1.服務安裝
[root@web01 ~]# systemctl start nginx

# 2.代理配置
upstream android {
        server 172.16.1.7:9090;
}

upstream ios {
        server 172.16.1.7:9091;
}

upstream pc {
        server 172.16.1.7:9092;
}


server {
	listen 80;
	server_name www.tcy.com;

	location / {
	        #如果客戶端來源是Android則跳轉到Android的資源;
                if ($http_user_agent ~* "Android") {
                        proxy_pass http://android;
                }

                #如果客戶端來源是Iphone則跳轉到Iphone的資源;
                if ($http_user_agent ~* "Iphone") {
                        proxy_pass http://ios;
                }

                #如果客戶端是IE瀏覽器則返回403錯誤;
                if ($http_user_agent ~* "MSIE") {
                        return 403;
                }

                #默認跳轉pc資源;
                proxy_pass http://pc;
        }
}

# 3.檢測語法並啟動服務
[root@lb01 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@lb01 ~]# systemctl start nginx

# 4.網頁測試(前提域名解析好)
http://www.tcy.com/

  • 默認訪問(圖一)

  • 模擬iphone訪問,頁面跳轉至ios頁面

  • 模擬安卓用戶訪問


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM