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

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

什麼是rewrite

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

就是修改url,提升用戶體驗html

rewrite的用途

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

什麼是僞靜態?mysql

本來的動態頁面,須要調用數據庫,可是在瀏覽器中的url裏面,返回的是一個靜態頁面,以html,css,js,shtml結尾。linux

爲何要作僞靜態?nginx

  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(...)標籤從新發起請求。web

break請求:
一、請求rewrite.gong.com/break
二、首先:會去查找本地的/website/test/index.html;
三、若是找到了,則返回return的內容;
四、若是沒找到該目錄則報錯404,若是找到該目錄沒找到對應的文件則403

last請求:
一、請求rewrite.gong.com/last
二、首先:會去查找本地的/website/test/index.html;
三、若是找到了,則返回/website/test/index.html的內容;mv
四、若是沒找到,會對當前server從新的發起一次請求,rewrite.gong.com/test/
五、若是有location匹配上,則直接返回該location的內容。
四、若是也沒有location匹配,再返回404;

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

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 跳轉json

結論

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;
        }
}

# 二、建立站點
[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
# 一、編輯配置文件
[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;
        }
}

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

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

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

MariaDB [(none)]> create database dis;

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

# 五、從新加載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
相關文章
相關標籤/搜索