<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 7536字,需瀏覽 16分鐘

           ·

          2020-12-20 11:12

          閱讀目錄

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

          • 二:理解 Rewrite指令 使用

          • 三:理解if指令

          • 四:理解防盜鏈及nginx配置

          ??簡(jiǎn)介:Rewrite是Nginx服務(wù)器提供的一個(gè)重要的功能,它可以實(shí)現(xiàn)URL重定向功能。

          回到頂部

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

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

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

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

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

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

          回到頂部

          二:理解 Rewrite指令 使用

          該指令是通過(guò)正則表達(dá)式的使用來(lái)改變URI。可以同時(shí)存在一個(gè)或多個(gè)指令。需要按照順序依次對(duì)URL進(jìn)行匹配和處理。

          該指令可以在server塊或location塊中配置,其基本語(yǔ)法結(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臨時(shí)重定向,瀏覽器地址會(huì)顯示跳轉(zhuǎn)新的URL地址。
          permanent:?返回301永久重定向。瀏覽器地址會(huì)顯示跳轉(zhuǎn)新的URL地址。

          比如如下列子:

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

          說(shuō)明:
          rewrite?為固定關(guān)鍵字,表示開(kāi)始進(jìn)行rewrite匹配規(guī)則。
          regex?為 ^/(.*)。這是一個(gè)正則表達(dá)式,匹配完整的域名和后面的路徑地址。
          replacement就是 http://www.baidu.com/1" role="presentation" style=" display: inline; line-height: 1.8; word-spacing: normal; overflow-wrap: normal; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; ">111是取regex部分()里面的內(nèi)容。如果匹配成功后跳轉(zhuǎn)到的URL。
          flag?就是 permanent,代表永久重定向的含義,即跳轉(zhuǎn)到 http://www.baidu.com/$1 地址上。

          下面我們來(lái)做個(gè)簡(jiǎn)單的demo來(lái)模擬下:

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

          const Koa = require('koa');const app = new Koa();
          const router = require('koa-router')();
          // 添加路由router.get('/', ctx => { ctx.body = '

          歡迎光臨index page 頁(yè)面

          '
          ;
          });
          router.get('/home', ctx => { ctx.body = '

          歡迎光臨home頁(yè)面

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

          404...

          '
          });
          // 加載路由中間件app.use(router.routes());
          app.listen(3001, () => { console.log('server is running at http://localhost:3001');});

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

          cd /usr/local/etc/nginx

          然后使用命令:sudo open /usr/local/etc/nginx/nginx.conf -a 'sublime text' 命令打開(kāi) 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)聽(tīng)端口號(hào)是8088,然后server_name 配置設(shè)置為 xxx.abc.com, 然后當(dāng)我們?cè)L問(wèn) http://xxx.abc.com:8088/的時(shí)候,會(huì)先反向代理到我們的http://127.0.0.1:3001下的node對(duì)應(yīng)的頁(yè)面上來(lái),反向代理完成后,會(huì)使用 rewrite 重定向百度頁(yè)面去了。如上配置完成后,我們需要重啟下nginx服務(wù)器;使用命令:

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

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

          回到頂部

          三:理解if指令

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

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

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

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

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

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

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

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

          比如如下:

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

          2. 判斷請(qǐng)求的文件是否存在

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

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

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

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

          現(xiàn)在我們使用if指令來(lái)對(duì)nginx加一些判斷;比如說(shuō)我們?cè)L問(wèn)http://xxx.abc.com:8080/home時(shí)候,如果$host = 'xxx.abc.com' 的時(shí)候,就做重定向跳轉(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 如上配置,如果我們?cè)L問(wèn) http://xxx.abc.com:8088 的時(shí)候,它就會(huì)重定向到 http://www.cnblogs.com 來(lái)了。

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

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

          四:理解防盜鏈及nginx配置

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

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

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

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

          Nginx中有一個(gè)指令 valid_referers. 該指令可以用來(lái)獲取 Referer 頭域中的值,并且根據(jù)該值的情況給 Nginx全局變量?invalidrefererReferer沒(méi)validreferers" role="presentation" style=" display: inline; line-height: 1.8; word-spacing: normal; overflow-wrap: normal; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; ">?????????????????????沒(méi)?????????????invalidrefererReferer沒(méi)validreferersinvalid_referer變量將會(huì)賦值為1. valid_referers 指令基本語(yǔ)法如下:

          valid_referers  none | blocked | server_names | string

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

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

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

          1. 根據(jù)請(qǐng)求文件類型實(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ò)連接對(duì)以 gif、jpg、png為后綴的圖片資源時(shí)候、當(dāng)有以swf、flv為后綴的媒體資源時(shí)、或以 rar、zip為后綴的壓縮資源發(fā)起請(qǐng)求時(shí),如果檢測(cè)到Referer頭域中沒(méi)有符合 valid_referers指令的話,那么說(shuō)明不是本站的資源請(qǐng)求。

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

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

          2. 根據(jù)請(qǐng)求目錄實(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;    }  }}

          瀏覽 45
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  中国一级免费毛片 | 成人激情开心网 | 色色影音 | 欧美国产日韩色图 | 国产7777 |