nginx rewite重定向詳解及實例解析


靜態和動態最大的區別是是否調用數據庫。

什么是rewrite

將瀏覽器發送到服務器的請求重寫,然后再返回給用戶。

就是修改url,提高用戶體驗

rewrite的用途

  1. 80強轉443 (優化用戶體驗)
  2. 匹配客戶端規則,返回對應頁面 (優化用戶體驗),電腦登陸淘寶為www.taobao.com 手機登陸是m.taobao.com
  3. 偽靜態(便於做SEO)

什么是偽靜態?

原本的動態頁面,需要調用數據庫,但是在瀏覽器中的url里面,返回的是一個靜態頁面,以html,css,js,shtml結尾。

為什么要做偽靜態?

  1. 安裝
  2. 為了百度的推廣做SEO

rewrite使用

rewrite標記flage

flag 作用
last 本條規則匹配完成后,停止匹配,不再匹配后面的規則 開發做
break 本條規則匹配完成后,停止匹配,不再匹配后面的規則 開發做
redirect 返回302臨時重定向,地址欄會顯示跳轉后的地址
permanent 返回301永久重定向,地址欄會顯示跳轉后的地址
[root@web02 /etc/nginx/conf.d]# vi rewrite.conf
server {
        listen 80;
        server_name rewrite.gong.com;
        root /website;

        location ~ ^/break {
                rewrite ^/break /test/ break;
        }
        location ~ ^/last {
                rewrite ^/last /test/ last;
        }
        location /test/ {
                default_type application/json;
                return 200 "ok";
        }
}

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

break請求:
1、請求rewrite.gong.com/break
2、首先:會去查找本地的/website/test/index.html;
3、如果找到了,則返回return的內容;
4、如果沒找到該目錄則報錯404,如果找到該目錄沒找到對應的文件則403

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

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

redirect和permanent的區別

[root@web01 /etc/nginx/conf.d]# vi blog_rewrite.conf 
server {
        listen 80;
        server_name www.linux.com;

        location / {
                root /website/dist;
                index index.html;
        }

        location /download {
                rewrite ^(.*)$ http://download.linux.com redirect;
                # return 302 "http://download.linux.com";
        }

        location /friends {
                rewrite ^(.*)$ http://friend.linux.com permanent;
                # return 302 "http://friend.linux.com";
        }
        location /blog {
                # rewrite ^(.*)$ http://blog.linux.com redirect;
                return 302 "http://blog.linux.com";
        }
}

訪問下載站點的時候使用的redirect302 跳轉

訪問下載站點的時候使用的permanent301 跳轉

結論

301 和 302 的不同,永久重定向在不清除本地緩存的情況下,服務端掛了,客戶端也可以重定向。(.\*)和 ^(.\*)$ 的區別,前者匹配uri后者匹配整個url 。

rewrite案例

案例一

用戶訪問/abc/1.html實際上真實訪問的是/ccc/bbb/2.html

# 瀏覽器輸入rewrite.gong.com/abc 的時候會自動跳轉
[root@web02 /etc/nginx/conf.d]# vi rewrite.conf 
server {
        listen 80;
        server_name rewrite.gong.com;
        root /website;
        index index.html;

        location /abc {
        		# (.*) 表示的是只替換uri部分
                rewrite (.*) /ccc/bbb/2.html redirect;
                 #return 302 /ccc/bbb/2.html;
        }
}

# 2、創建站點
[root@web02 /website]# mkdir -p ccc/bbb
[root@web02 /website]# echo 123 > ccc/bbb/2.html

案例二

用戶訪問/2018/ccc/2.html實際上真實訪問的是/2014/ccc/bbb/2.html

[root@web02 /etc/nginx/conf.d]# vi rewrite.conf 
server {
        listen 80;
        server_name rewrite.gong.com;
        root /website;
        index index.html;

        location /2018 {
        
        		# 這種寫法具有一定的可擴展性,引入了變量。
                rewrite ^/2018/(.*)$ /2014/$1 redirect;
                # 如果使用這種寫法,在重定向目錄過多的情況下顯然不好使。
                # rewrite (.*) /2014/ccc/bbb/2.html redirect;
        }
}

[root@web02 /website]# mkdir -p 2014/ccc/bbb/
[root@web02 /website]# echo 222 > 2014/ccc/bbb/2.html

案例三

用戶訪問/test實際上真實訪問的是rewrite.gong.com

[root@web02 /etc/nginx/conf.d]# vi rewrite.conf 
server {
        listen 80;
        server_name rewrite.gong.com;
        root /website;
        index index.html;

        location /test {
                rewrite (.*) http://rewrite.gong.com redirect;
        }
}

這中就像是平時在訪問網站的時候在后面輸入index.html,會自動的變成一個域名。

案例四

用戶訪問course-11-22-33.html實際上真實訪問的是/course/11/22/33/course_33.html

[root@web02 /etc/nginx/conf.d]# vi rewrite.conf 
server {
        listen 80;
        server_name rewrite.gong.com;
        root /website;

        location / {
        		# 這里需要引入變量,如果說在沒有變量的情況下,每變一個uri就要配置一條rewrite就不適用了
                rewrite ^/course-(.*)-(.*)-(.*).html /course/$1/$2/$3/course_$3.html  redirect;
                 #固定配法
                #rewrite ^/course-(.*) /course/11/22/33/course_33.html redirect;
        }
}


[root@web02 /website]# mkdir -p course/11/22/33/
[root@web02 /website]# echo course > course/11/22/33/course_33.html

案例五

http重定向https

[root@web02 /etc/nginx/conf.d]# vi rewrite.conf 
server {
        listen 80;
        server_name rewrite.gong.com;

        location / {
                rewrite ^(.*)$ https://rewrite.gong.com  redirect;
        }
}

瀏覽器輸入rewrite.gong.com會自動的跳轉到 https://rewrite.gong.com

搭建Discuss

環境

角色 IP 主機名
web服務器 10.0.0.8 web02
數據庫服務器 10.0.0.51 db01
# 1、編輯配置文件
[root@web02 /etc/nginx/conf.d]# vi dis.conf 
server {
        listen 80;
        server_name dis.gong.com;
        root /website/upload;
        index index.php;

        location ~ \.php$ {
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

                include fastcgi_params;
        }
}

# 2、解壓寫代碼
[root@web02 /website]# unzip Discuz_X3.3_SC_GBK.zip

# 3、授權
[root@web02 ~]# chown www.www -R /website/

# 4、配置數據庫服務器
[root@db01 ~]# mysql -uroot -p123

MariaDB [(none)]> create database dis;

MariaDB [(none)]> grant all on dis.* to dis_user@'%' identified by '123';

# 5、重新加載nginx配置文件
[root@web02 ~]# nginx -s reload

把網頁上自動生成的放到配置文件中。

root@web02 /etc/nginx/conf.d]# cat dis.conf 
server {
	listen 80;
	server_name dis.gong.com;
	root /website/upload;
	index index.php;

	rewrite ^([^\.]*)/topic-(.+)\.html$ $1/portal.php?mod=topic&topic=$2 last;
	rewrite ^([^\.]*)/article-([0-9]+)-([0-9]+)\.html$ $1/portal.php?mod=view&aid=$2&page=$3 last;
	rewrite ^([^\.]*)/forum-(\w+)-([0-9]+)\.html$ $1/forum.php?mod=forumdisplay&fid=$2&page=$3 last;
	rewrite ^([^\.]*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=viewthread&tid=$2&extra=page%3D$4&page=$3 last;
	rewrite ^([^\.]*)/group-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=group&fid=$2&page=$3 last;
	rewrite ^([^\.]*)/space-(username|uid)-(.+)\.html$ $1/home.php?mod=space&$2=$3 last;
	rewrite ^([^\.]*)/blog-([0-9]+)-([0-9]+)\.html$ $1/home.php?mod=space&uid=$2&do=blog&id=$3 last;
	rewrite ^([^\.]*)/(fid|tid)-([0-9]+)\.html$ $1/archiver/index.php?action=$2&value=$3 last;
	rewrite ^([^\.]*)/([a-z]+[a-z0-9_]*)-([a-z0-9_\-]+)\.html$ $1/plugin.php?id=$2:$3 last;
	if (!-e $request_filename) {
		return 404;
}

	location ~ \.php$ {
		fastcgi_pass 127.0.0.1:9000;
		fastcgi_index index.php;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

		include fastcgi_params;
	}
}

nginx中的常用變量

Rewrite與Nginx全局變量

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

$remote_addr        //獲取客戶端ip
$binary_remote_addr //客戶端ip(二進制)
$remote_port        //客戶端port,如:50472
$remote_user        //已經經過Auth Basic Module驗證的用戶名
$host           //請求主機頭字段,否則為服務器名稱,如:blog.sakmon.com
$request        //用戶請求信息,如:GET ?a=1&b=2 HTTP/1.1
$request_filename   //當前請求的文件的路徑名,由root或alias和URI request組合而成,如:/2013/81.html
$status         //請求的響應狀態碼,如:200
$body_bytes_sent        // 響應時送出的body字節數數量。即使連接中斷,這個數據也是精確的,如:40
$content_length        // 等於請求行的“Content_Length”的值
$content_type          // 等於請求行的“Content_Type”的值
$http_referer          // 引用地址
$http_user_agent      // 客戶端agent信息,如:Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36
$args            //與$query_string相同 等於當中URL的參數(GET),如a=1&b=2
$document_uri        //與$uri相同  這個變量指當前的請求URI,不包括任何參數(見$args) 如:/2013/81.html
$document_root       //針對當前請求的根路徑設置值
$hostname        //如:centos53.localdomain
$http_cookie        //客戶端cookie信息
$cookie_COOKIE      //cookie COOKIE變量的值
$is_args    //如果有$args參數,這個變量等於”?”,否則等於”",空值,如?
$limit_rate //這個變量可以限制連接速率,0表示不限速
$query_string       // 與$args相同 等於當中URL的參數(GET),如a=1&b=2
$request_body      // 記錄POST過來的數據信息
$request_body_file  //客戶端請求主體信息的臨時文件名
$request_method       //客戶端請求的動作,通常為GET或POST,如:GET
$request_uri          //包含請求參數的原始URI,不包含主機名,如:/2013/81.html?a=1&b=2
$scheme            //HTTP方法(如http,https),如:http
$uri            //這個變量指當前的請求URI,不包括任何參數(見$args) 如:/2013/81.html
$request_completion //如果請求結束,設置為OK. 當請求未結束或如果該請求不是請求鏈串的最后一個時,為空(Empty),如:OK
$server_protocol    //請求使用的協議,通常是HTTP/1.0或HTTP/1.1,如:HTTP/1.1
$server_addr        //服務器IP地址,在完成一次系統調用后可以確定這個值
$server_name        //服務器名稱,如:blog.sakmon.com
$server_port        //請求到達服務器的端口號,如:80
$server_name    # 當前用戶請求的域名

server {
        listen 80;
        server_name test.drz.com;
       # 重定向為https
        rewrite ^(.*)$ https://$server_name$1;
}
$request_filename 請求的文件路徑名(帶網站的主目錄/code/images/test.jpg)
$request_uri 當前請求的文件路徑(不帶網站的主目錄/inages/test.jpg)

#大多數用於http協議轉gttps協議
server {
        listen 80;
        server_name php.drz.com;
        # return的方式也可用作跳轉。
        return 302 https://$server_name$request_uri;
}
$scheme 用的協議,比如http或者https

rewrite匹配的優先級

匹配 優先級
server中的rewrite 1
location匹配 2
location中的rewrite 3


免責聲明!

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



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