佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > 詳解Nginx中的Rewrite的重定向配置與實(shí)踐

詳解Nginx中的Rewrite的重定向配置與實(shí)踐

熱門標(biāo)簽:使用U盤裝系統(tǒng) 網(wǎng)站建設(shè) 阿里云 檢查注冊表項(xiàng) 智能手機(jī) 硅谷的囚徒呼叫中心 百度競價點(diǎn)擊價格的計(jì)算公式 美圖手機(jī)

一:理解地址重寫 與 地址轉(zhuǎn)發(fā)的含義。

地址重寫與地址轉(zhuǎn)發(fā)是兩個不同的概念。

地址重寫 是為了實(shí)現(xiàn)地址的標(biāo)準(zhǔn)化,比如我們可以在地址欄中中輸入 www.baidu.com. 我們也可以輸入 www.baidu.cn. 最后都會被重寫到 www.baidu.com 上。瀏覽器的地址欄也會顯示www.baidu.com。

地址轉(zhuǎn)發(fā):它是指在網(wǎng)絡(luò)數(shù)據(jù)傳輸過程中數(shù)據(jù)分組到達(dá)路由器或橋接器后,該設(shè)備通過檢查分組地址并將數(shù)據(jù)轉(zhuǎn)發(fā)到最近的局域網(wǎng)的過程。

因此地址重寫和地址轉(zhuǎn)發(fā)有以下不同點(diǎn):

1. 地址重寫會改變?yōu)g覽器中的地址,使之變成重寫成瀏覽器最新的地址。而地址轉(zhuǎn)發(fā)他是不會改變?yōu)g覽器的地址的。
2. 地址重寫會產(chǎn)生兩次請求,而地址轉(zhuǎn)發(fā)只會有一次請求。
3. 地址轉(zhuǎn)發(fā)一般發(fā)生在同一站點(diǎn)項(xiàng)目內(nèi)部,而地址重寫且不受限制。
4. 地址轉(zhuǎn)發(fā)的速度比地址重定向快。

二:理解 Rewrite指令 使用

該指令是通過正則表達(dá)式的使用來改變URI??梢酝瑫r存在一個或多個指令。需要按照順序依次對URL進(jìn)行匹配和處理。

該指令可以在server塊或location塊中配置,其基本語法結(jié)構(gòu)如下:

rewrite regex replacement [flag];

rewrite的含義:該指令是實(shí)現(xiàn)URL重寫的指令。
regex的含義:用于匹配URI的正則表達(dá)式。
replacement:將regex正則匹配到的內(nèi)容替換成 replacement。
flag: flag標(biāo)記。

flag有如下值:

  • last: 本條規(guī)則匹配完成后,繼續(xù)向下匹配新的location URI 規(guī)則。(不常用)
  • break: 本條規(guī)則匹配完成即終止,不再匹配后面的任何規(guī)則(不常用)。
  • redirect: 返回302臨時重定向,瀏覽器地址會顯示跳轉(zhuǎn)新的URL地址。
  • permanent: 返回301永久重定向。瀏覽器地址會顯示跳轉(zhuǎn)新的URL地址。

比如如下列子:

rewrite ^/(.*) http://www.baidu.com/$1 permanent;

說明:
rewrite 為固定關(guān)鍵字,表示開始進(jìn)行rewrite匹配規(guī)則。
regex 為 ^/(.*)。 這是一個正則表達(dá)式,匹配完整的域名和后面的路徑地址。
replacement就是 http://www.baidu.com/$1 這塊了,其中$1是取regex部分()里面的內(nèi)容。如果匹配成功后跳轉(zhuǎn)到的URL。
flag 就是 permanent,代表永久重定向的含義,即跳轉(zhuǎn)到 http://www.baidu.com/$1 地址上。

下面我們來做個簡單的demo來模擬下:

1. 在我們的測試項(xiàng)目下有個app.js. 代碼如下:

const Koa = require('koa');
const app = new Koa();

const router = require('koa-router')();

// 添加路由
router.get('/', ctx => {
 ctx.body = '<h1>歡迎光臨index page 頁面</h1>';
});

router.get('/home', ctx => {
 ctx.body = '<h1>歡迎光臨home頁面</h1>';
});

router.get('/404', ctx => {
 ctx.body = '<h1>404...</h1>'
});

// 加載路由中間件
app.use(router.routes());

app.listen(3001, () => { 
 console.log('server is running at http://localhost:3001');
});

然后在命令行中 運(yùn)行 node app.js 后,運(yùn)行,我們就可以在瀏覽器中 訪問 http://localhost:3001 就可以訪問到我們對應(yīng)的頁面了。但是現(xiàn)在我想把該node項(xiàng)目部署到我本地的nginx服務(wù)器上。nginx安裝請看我這篇文章 然后我想使用域名來訪問我們的項(xiàng)目,因此我們需要在我們的nginx.conf中配置一下:

cd /usr/local/etc/nginx

然后使用命令:sudo open /usr/local/etc/nginx/nginx.conf -a 'sublime text' 命令打開 nginx.conf 配置如下:

worker_processes 1;

events {
  worker_connections 1024;
}
http {
  include    mime.types;
  default_type application/octet-stream;

  sendfile    on;
  #tcp_nopush   on;

  #keepalive_timeout 0;
  keepalive_timeout 65;

  #gzip on;

  server {
   listen    8081;
   server_name localhost;
   location / {
    root  html;
    index index.html index.htm; 
   }
   error_page  500 502 503 504 /50x.html;
   location = /50x.html {
    root  html;
   }
  }
  server {
   listen 8088;
   server_name xxx.abc.com;
   location / {
    proxy_pass http://127.0.0.1:3001;
    rewrite ^/(.*) http://www.baidu.com permanent;
   }
  }
}

如上代碼,我監(jiān)聽端口號是8088,然后server_name 配置設(shè)置為 xxx.abc.com, 然后當(dāng)我們訪問 http://xxx.abc.com:8088/的時候,會先反向代理到我們的http://127.0.0.1:3001下的node對應(yīng)的頁面上來,反向代理完成后,會使用 rewrite 重定向百度頁面去了。如上配置完成后,我們需要重啟下nginx服務(wù)器;使用命令:

然后當(dāng)我們在瀏覽器訪問 http://xxx.abc.com:8088/ 的時候,會執(zhí)行如下圖所示,它會先對 http://xxx.abc.com:8088/ 進(jìn)行永久重定向(301), 然后會訪問百度(307),臨時重定向到百度頁面來,最終加載百度頁面的地址;如下演示所示:

但是如果我把 permanent 改成 redirect 的話,比如nginx配置:rewrite ^/(.*) http://www.baidu.com redirect;后,它就會變成302臨時重定向了。如下所示:

三:理解if指令

該指令用來支持條件判斷的,并且根據(jù)條件判斷結(jié)果來選擇不同的nginx的配置,我們可以在server塊或location塊中配置該指令,它的語法結(jié)構(gòu)為:

if (condition) {
 // ....
}

condition 是布爾值 true/false的含義。

Rewrite 指令可用的全局變量如下:

1. $args: 該變量中存放了請求URL中的請求指令。比如 http://127.0.0.1:3001?arg1=value1&arg2=value2 中的
"arg1=value1&arg2=value2"。
2. $content_length: 該變量中存放了請求頭中的Content-length字段。
3. $content_type: 該變量中存放了請求頭中的 Content-type字段。
4. $document_root: 該變量中存放了針對當(dāng)前請求的根路徑。
5. $document_uri: 該變量中存放了請求的當(dāng)前URI, 但是不包括請求指令。比如 http://xxx.abc.com/home/1?arg1=value1&
arg2=value2; 中的 "/home/1"
6. $host: 變量中存放了請求的URL中的主機(jī)部分字段,比如http://xxx.abc.com:8080/home中的 xxx.abc.com.
7. $http_host: 該變量與$host唯一區(qū)別帶有端口號:比如上面的是 xxx.abc.com:8080
8. $http_user_agent: 變量中存放客戶端的代理信息。
9. $http_cookie, 該變量中存放客戶端的cookie信息。
10. $remote_addr 該變量中存放客戶端的地址。
11. $remote_port 該變量中存放了客戶端與服務(wù)器建立連接的端口號。
12. $remote_user 變量中存放客戶端的用戶名。
13. $request_body_file 變量中存放了發(fā)給后端服務(wù)器的本地文件資源的名稱
14. $request_method 變量中存放了客戶端的請求方式,比如 'GET'、'POST'等。
15. $request_filename 變量中存放了當(dāng)前請求的資源文件的路徑名。
16. $request_uri 變量中存放了當(dāng)前請求的URI,并且?guī)д埱笾噶睢?br /> 17. $query_string 和變量$args含義一樣。
18. $scheme 變量中存放了客戶端請求使用的協(xié)議,比如 'http', 'https'等。
19. $server_protocol 變量中存放了客戶端請求協(xié)議的版本, 比如 'HTTP/1.0'、'HTTP/1.1' 等。
..... 等等

正則表達(dá)式的基本語法:

1. 對變量進(jìn)行匹配

'~' 表示匹配過程中對大小寫敏感。
'~*' 表示匹配過程中對大小寫不敏感。
'!~' 如果 '~' 匹配失敗時,那么該條件就為true。
'!~*' 如果 '~*' 匹配失敗時,那么該條件就為true。

比如如下:

if ($http_user_agent ~ MSIE) {
 // 代碼的含義:$http_user_agent值中是否含有 MSIE 字符串,如果包含為true,否則為false
}

2. 判斷請求的文件是否存在

'-f' 如果請求的文件存在,那么該條件為true。
'!-f' 如果該文件的目錄存在,該文件不存在,那么返回true。如果該文件和目錄都不存在,則為false。
如果請求的目錄不存在,請求的文件存在,也為false。

if (-f $request_filename) {
 // 判斷請求的文件是否存在
}

if (!-f $request_filename) {
 // 判斷請求的文件是否不存在
}

3. 判斷請求的目錄是否存在使用 '-d' 和 '!-d'

使用 '-d',如果請求的目錄存在,則返回true。否則返回false。
使用 '!-d', 如果請求的目錄不存在,但是該請求的上級目錄存在,則返回true。如果該上級目錄不存在,則返回false.... 等等其他一些語法,不多介紹。

現(xiàn)在我們使用if指令來對nginx加一些判斷;比如說我們訪問http://xxx.abc.com:8080/home時候,如果$host = 'xxx.abc.com' 的時候,就做重定向跳轉(zhuǎn),nginx配置代碼如下:

server {
 listen 8088;
 server_name xxx.abc.com;
 location / {
  proxy_pass http://127.0.0.1:3001;
  if ($host = 'xxx.abc.com') {
   rewrite ^/(.*) http://www.cnblogs.com redirect;
  }
 }
}

nginx 如上配置,如果我們訪問 http://xxx.abc.com:8088 的時候,它就會重定向到 http://www.cnblogs.com 來了。

比如更多的判斷,比如如果用戶代理是手機(jī)訪問的話,直接跳轉(zhuǎn)到某個頁面去,也可以使用if判斷。比如如下:

if ( $http_user_agent ~* "(Android)|(iPhone)|(Mobile)|(WAP)|(UCWEB)" ){
 rewrite ^/$ http://www.cnblogs.com permanent;
}

四:理解防盜鏈及nginx配置

什么是防盜鏈?盜鏈可以理解盜圖鏈接,也就是說把別人的圖片偷過來用在自己的服務(wù)器上,那么防盜鏈可以理解為防止其他人把我的圖片盜取過去。

防盜鏈的實(shí)現(xiàn)原理:客戶端向服務(wù)器端請求資源時,為了減少網(wǎng)絡(luò)帶寬,提高響應(yīng)時間,服務(wù)器一般不會一次將所有資源完整地傳回客戶端。比如請求一個網(wǎng)頁時,首先會傳回該網(wǎng)頁的文本內(nèi)容,當(dāng)客戶端瀏覽器在解析文本的過程中發(fā)現(xiàn)有圖片存在時,會再次向服務(wù)器發(fā)起對該圖片資源的請求,服務(wù)器將存儲的圖片資源再發(fā)送給客戶端。但是如果這個圖片是鏈接到其他站點(diǎn)的服務(wù)器上去了呢,比如在我項(xiàng)目中,我引用了的是淘寶中的一張圖片的話,那么當(dāng)我們網(wǎng)站重新加載的時候,就會請求淘寶的服務(wù)器,那么這就很有可能造成淘寶服務(wù)器負(fù)擔(dān)。因此這個就是盜鏈行為。因此我們要實(shí)現(xiàn)防盜鏈。

實(shí)現(xiàn)防盜鏈:使用http協(xié)議中請求頭部的Referer頭域來判斷當(dāng)前訪問的網(wǎng)頁或文件的源地址。通過該頭域的值,我們可以檢測訪問目標(biāo)資源的源地址。如果目標(biāo)源地址不是我們自己站內(nèi)的URL的話,那么這種情況下,我們采取阻止措施,實(shí)現(xiàn)防盜鏈。但是注意的是:Referer頭域中的值是可以被更改的。因此該方法也不能完全安全阻止防盜鏈。

使用Nginx服務(wù)器的Rewrite功能實(shí)現(xiàn)防盜鏈。

Nginx中有一個指令 valid_referers. 該指令可以用來獲取 Referer 頭域中的值,并且根據(jù)該值的情況給 Nginx全局變量 $invalid_referer 賦值。如果Referer頭域中沒有符合 valid_referers指令的值的話,$invalid_referer變量將會賦值為1.

valid_referers 指令基本語法如下:

valid_referers none | blocked | server_names | string

none: 檢測Referer頭域不存在的情況。
blocked: 檢測Referer頭域的值被防火墻或者代理服務(wù)器刪除或偽裝的情況。那么在這種情況下,該頭域的值不以"http://" 或 "https://" 開頭。

server_names: 設(shè)置一個或多個URL,檢測Referer頭域的值是否是URL中的某個。

因此我們有了 valid_referers指令和$invalid_referer變量的話,我們就可以通過 Rewrite功能來實(shí)現(xiàn)防盜鏈。
下面我們介紹兩種方案:第一:根據(jù)請求資源的類型。第二:根據(jù)請求目錄。

1. 根據(jù)請求文件類型實(shí)現(xiàn)防盜鏈配置實(shí)列如下:

server {
 listen 8080;
 server_name xxx.abc.com
 location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip)$ {
  valid_referers none blocked www.xxx.com www.yyy.com *.baidu.com *.tabobao.com;
  if ($invalid_referer) {
   rewrite ^/ http://www.xxx.com/images/forbidden.png;
  }
 }
}

如上基本配置,當(dāng)有網(wǎng)絡(luò)連接對以 gif、jpg、png為后綴的圖片資源時候、當(dāng)有以swf、flv為后綴的媒體資源時、或以 rar、zip為后綴的壓縮資源發(fā)起請求時,如果檢測到Referer頭域中沒有符合 valid_referers指令的話,那么說明不是本站的資源請求。

location ~* ^.+\.(gif|jpg|png|swf|flv|rar|zip)$ 該配置的含義是 設(shè)置防盜鏈的文件類型。

valid_referers none blocked www.xxx.com www.yyy.com *.baidu.com *.tabobao.com; 可以理解為白名單,允許文件鏈出的域名白名單,如果請求的資源文件不是以這些域名開頭的話,就說明請求的資源文件不是該域下的請求,因此可以判斷它是盜鏈。因此如果不是該域下的請求,就會使用 Rewrite進(jìn)行重定向到 http://www.xxx.com/images/forbidden.jpg 這個圖片,比如這張圖片是一個x或其他的標(biāo)識,然后其他的網(wǎng)站就訪問不了你這個圖片哦。

2. 根據(jù)請求目錄實(shí)現(xiàn)防盜鏈的配置實(shí)列如下:

server {
 listen 8080;
 server_name xxx.abc.com
 location /file/ {
  root /server/file/;
  valid_referers none blocked www.xxx.com www.yyy.com *.baidu.com *.tabobao.com;
  if ($invalid_referer) {
   rewrite ^/ http://www.xxx.com/images/forbidden.png;
  }
 }
}

到此這篇關(guān)于詳解Nginx中的Rewrite的重定向配置與實(shí)踐的文章就介紹到這了,更多相關(guān)Nginx Rewrite重定向內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

標(biāo)簽:湖北 通遼 山南 湘潭 煙臺 黃山 賀州 懷化

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《詳解Nginx中的Rewrite的重定向配置與實(shí)踐》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    玛沁县| 昭平县| 高碑店市| 巴塘县| 瑞丽市| 于田县| 平果县| 延吉市| 邢台县| 沙洋县| 乌海市| 深泽县| 射阳县| 贵州省| 古田县| 岚皋县| 湖州市| 上犹县| 平果县| 桐梓县| 崇州市| 蓬溪县| 玉林市| 罗江县| 中宁县| 巴中市| 海南省| 尉氏县| 偏关县| 黄骅市| 平安县| 钦州市| 三都| 安福县| 布尔津县| 南昌县| 策勒县| 体育| 桦川县| 南平市| 光山县|