nginx 路由配置

  nginx中location對url匹配;php

  語法:location [=|~|~*|^~] /uri/ { … }html

  當匹配中符合條件的location,則執行內部指令;若是使用正則表達式,必須使用~*代表不區分大小寫或者~區分大小寫匹配;例如:location ~* \.(gif|jpg|jpeg)$ ;當配皮成功後,將中止往下匹配;若是沒有找到,則使用常規自字符串處理結果;nginx

  若是不是用正則表達式;可以使用=嚴格匹配;web

  若是使用^~前綴用於一個常規字符串;表示若是路徑匹配,則不測試正則表達式;正則表達式

  總結:指令按下列順序被接受chrome

    1:=前綴的指令嚴格匹配這個查詢;若是找到中止往下匹配express

    2:掙下的常規字符串,長的在前,若是這個匹配使用^~前綴,匹配中止;瀏覽器

    3:正則表達式,按配置文件的順序;服務器

    4:若是第三步產生匹配。則使用這個結果;中止匹配;不然使用第二部的匹配結果;cookie

四個案例:

location = / {

    #只匹配/查詢

  }

  location / {

    #匹配任何查詢,全部請求都是以/開頭。可是正則表達式規則和長的塊規則將被優先匹配和查詢;

  }

  location ^~ /images/ {
    # 匹配任何已 /images/ 開頭的任何查詢而且中止搜索。任何正則表達式將不會被測試。
    }

  location ~* \.(gif|jpg|png)${

    #匹配任何以gif、jpg、png結尾的請求。而後全部/images/目錄的請求將使用第三個

  }

  例子請求:

    / -> configuration A

    /documents/document.html -> configuration B

    /images/1.gif -> configuration C

    /documents/1.jpg -> configuration D

 

八個location案例

location = / {  #精確匹配,/後面不能加任何字符串,符合此條件就直接返回數據,再也不像下匹配。
    if (-d $request_filename) {
         root /usr/local/nginx/html/;  #當用戶訪問newweb的時候,則顯示此目錄的內容,除此以外訪問其餘的任何目錄都不匹配。
  [動做A]
}

location  / {
  # 由於全部的地址都以/開頭,因此這條規則將匹配到全部請求,可是非精確匹配會採起正則和最長字符串會優先匹配,所以還會向下繼續匹配,好比當訪問/bbs的時候,還須要看下面是否更精確的匹配。
  [ 動做B] 
}

location /documents/ {
  # 匹配任何以 /documents/ 開頭的地址,匹配符合之後,還要繼續往下搜索
  # 若是後面的正則表達式都沒有匹配到,就匹配這一條
  [動做C] 
}

location ^~ /images/ {   #匹配任何以/images/ 開頭的任何請求而且中止搜索,後面任何正則表達式將不會被測試。
  # 匹配任何以 /images/ 開頭的地址,匹配符合之後,中止往下搜索正則,採用這一條。
  [動做D] 
}

location ~* \.(gif|jpg|jpeg)$ {  #~*爲不區分大小寫
  # 匹配全部以 gif,jpg或jpeg 結尾的請求
  # 然而,全部請求/images/下的圖片會被動做D匹配處理,由於動做D有^~會優先匹配並終止匹配,因此到達不了這一條正則
  [動做E] 
}

location /images/ {
  # 字符匹配到 /images/,繼續往下,會發現 ^~ 存在,若是動做D存在,則這一條就不生效。
  [動做F] 
}

location /images/abc {
  #最長字符匹配到 /images/abc,繼續往下,會發現 ^~ 存在,若是D存在,則這一條就不生效。
  #F與G的放置順序是沒有關係的
  [動做G] 
}

location ~ /images/abc/ {
  # 動做D存在,這一條不生效,若是註銷動做D,則會優先最長匹配 動做G 開頭的地址,而後向下匹配,到這一條的時候就會匹配並生效。
    [ configuration H ] 
}

 匹配優先級,順序 no優先級:
(location =) > (location 完整路徑) > (location ^~ 路徑) > (location ~,~* 正則順序) > (location 部分起始路徑) > (/)

上面的匹配結果
按照上面的location寫法,如下的匹配示例成立:

/ -> config A
精確徹底匹配,即便/index.html也匹配不了

/downloads/download.html -> config B
匹配B之後,往下沒有任何匹配,採用B

/images/1.gif -> configuration D
匹配到F,往下匹配到D,中止往下

/images/abc/def -> config D
最長匹配到G,往下匹配D,中止往下
你能夠看到 任何以/images/開頭的都會匹配到D並中止,FG寫在這裏是沒有任何意義的,H是永遠輪不到的,這裏只是爲了說明匹配順序

/documents/document.html -> config C
匹配到C,往下沒有任何匹配,採用C

/documents/1.jpg -> configuration E
匹配到C,往下正則匹配到E

/documents/Abc.jpg -> config CC
最長匹配到C,往下正則順序匹配到CC,不會往下到E

 

當匹配成功後location中可使用rewrite進行路由重寫;

  首先須要瞭解nginx rewrite中可使用到的全局變量;

  $args  :請求中get的參數,例如a=1&b=2;

  $body_remote_add  :二進制客戶地址

  $body_byte_sent  :相應時發送出去的body字節數數量,即便連接中斷這個數據也是精確的;

  $content_length  :請求頭中的Content_length字段

  $content_type  :請求中的Content_type字段

  $document_root  :當前請求在root指令中的位置;服務器中絕對路徑

  $document_url  :與uri相同

  $host  :請求主機頭字段,不然爲服務器名稱;

  $hostname  :保存了當前請求中不包含指令的uri,例如:http://www.aaa.com/index.php?a=1中的/index.php;

  $host  :請求的服務器名稱;

  $http_user_agent  :客戶端瀏覽器的詳細信息,若是使用 chrome 和Firefox 則訪問結果是

Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36 #chrome的瀏覽器信息
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0  #Firefox的瀏覽器信息

  $http_cookie  : 客戶端cookie信息;

  $limit_rate  :若是nginx服務器中使用limit_rate配置了顯示網絡速率,則會顯示,若是沒有則爲0

  $remote_addr  :客戶端的地址,每一個客戶端的公網ip,

  $remote_port  :客戶端請求nginx服務器時隨機打開的端口,這個每一個客戶端本身的端口;

  $remote_user  :已經通過auth basic module驗證的用戶名

  $request_body_file  :做反向代理是發給服務端的本地資源名稱

  $request_method  :請求志願的方式,get\put\delete等

  $request_filename  :請求的資源文件的路徑名稱

  $request_url  :請求參數的原始uri,不包含主機名;如"/index.php?a=1"

  $squery_string  :保存了url請求的指令,與$args相同

  $scheme  :請求協議;如http、https、ftp

  $server_protacpl  :保存了客戶端請求資源使用的協議的版本,如http/1.0、http/1.1

  $server_addr  :保存了服務器ip

  $server_name  :保存了服務器的主機名;該變量不必定是用戶訪問的域名,是你的server_name配的地址;

  $host  :保存了用戶訪問的域名

  $server_port  :服務器端口

  $uri與$document_uri相同  :不包含指令的uri地址

如www.aaa.com/index.php?a=1&b=2中的index.php

 

防盜鏈:注意location生效規則,不然防盜鏈不起做用。

配置參數說明:

  none

    'Referer' :來源頭部爲空的狀況

  blocked

    'Referer' :來源頭部不爲空,但裏面的值被代理或者防火牆刪除,這些值都不以http://或者https://開頭

  server_names

    'Referer' :來源頭部包含當前的server_name,就是域名

  arbitary string :任意字符串,定義服務器名或者可選的url前綴,主機名可使用*開頭或者結尾,在檢測來源頭部這個過程當中,來源域名中的主機端口將會被忽視;

  regular expression :正則表達式,表示排除https://或者http://開頭的字符串

下面兩個案例:

location ~* \.(gif|jpg|png|bmp)$ {
    valid_referers none blocked *.aaa.com server_names ~\.google\. ~\.baidu\.;
    if ($invalid_referer) {
        return 403;
        #rewrite ^/ http://www.aaa.com/1.jpg;
    }
}
以上全部來至aaa.com和域名中包含google和baidu的站點均可以訪問到當前站點的圖片,若是來源域名不在這個列表中,那麼$invalid_referer等於1,在if語句中返回一個403給用戶,這樣用戶便會看到一個403的頁面,若是使用下面的rewrite,那麼盜鏈的圖片都會顯示403.jpg。若是用戶直接在瀏覽器輸入你的圖片地址,那麼圖片顯示正常,由於它符合none這個規則.
location ~* \.(gif|jpg|png|swf|flv)$ { # 防盜鏈設置,對於後綴是gif、jgp等格式的生效
    valid_referers none blocked  a.com  *.a.com; #定義容許訪問的請求連接
    if ($invalid_referer) {
        return 404;
    }
}

none:在瀏覽器輸入網站域名直接訪問的請求,須要容許訪問的
blocked:有referer首部,可是referer首部被清除了,通常是防火牆改過的請求
server_name:帶服務器名稱的,通常是本機或其餘服務器的請求,a.com和*.a.com是本公司的域名,要容許訪問因而要先容許本機的訪問,再禁止其餘服務器的訪問
 location /public/admin/images/y.jpg {
      #valid_referers none blocked *.aaa.com server_names *.aaa.com    ;
      #valid_referers none blocked www.sss.com; #設置只有該域>    名能夠訪問
      valid_referers none blocked 111.111.111.11; #設置只有該域名能夠訪>if ($invalid_referer) {
          rewrite ^ http://baidu.com$request_uri?;
          return 403;
          rewrite ^/ http://www.aaa.com/1.jpg;
      }
 }

 

經常使用正則匹配

. : 匹配除換行符之外的任意字符
? : 重複0次或1次
+ : 重複1次或更屢次
* : 重複0次或更屢次
\d :匹配數字
^ : 匹配字符串的開始
$ : 匹配字符串的介紹
{n} : 重複n次
{n,} : 重複n次或更屢次
[c] : 匹配單個字符c
[a-z] : 匹配a-z小寫字母的任意一個
小括號()之間匹配的內容,能夠在後面經過$1來引用,$2表示的是前面第二個()裏的內容。正則裏面容易讓人困惑的是\轉義特殊字符。

 

參考if判斷語句

if ($http_user_agent ~ MSIE) { #若是客戶端是微軟的IE瀏覽器,就將請求rewrite到msie目錄下。
    rewrite ^(.*)$ /msie/$1 break;
} 

if ($http_cookie ~* "id=([^;]+)(?:;|$)") { # 若是cookie匹配正則,就設置變量$id等於正則引用部分
    set $id $1; 設置$id等於正則第一個括號內匹配的部分
 } 

if ($request_method = POST) { #若是提交方法爲POST,則返回狀態405(Method not allowed)。return不能返回301,302
    return 405;
} 

if ($slow) { #限速,$slow能夠經過 set 指令設置
    limit_rate 10k;
} 

if (!-f $request_filename){ #若是請求的文件名不存在,則反向代理到localhost 。這裏的break也是中止rewrite檢查
    break;
    proxy_pass  http://127.0.0.1; 
} 

if ($args ~ post=140){ #若是query string中包含"post=140",永久重定向到example.com
    rewrite ^ http://example.com/ permanent;
}

 

nginx 配置案例參考

http {
    # 定義image日誌格式
    log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status;
    # 開啓重寫日誌
    rewrite_log on;

    server {
        root /home/www;

        location / {
                # 重寫規則信息
                error_log logs/rewrite.log notice; 
                # 注意這裏要用‘’單引號引發來,避免{}
                rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;
                # 注意不能在上面這條規則後面加上「last」參數,不然下面的set指令不會執行
                set $image_file $3;
                set $image_type $4;
        }

        location /data {
                # 指定針對圖片的日誌格式,來分析圖片類型和大小
                access_log logs/images.log mian;
                root /data/images;
                # 應用前面定義的變量。判斷首先文件在不在,不在再判斷目錄在不在,若是還不在就跳轉到最後一個url裏
                try_files /$arg_file /image404.html;
        }
        location = /image404.html {
                # 圖片不存在返回特定的信息
                return 404 "image not found\n";
        }
}
相關文章
相關標籤/搜索