nginx 路由配置


  nginx中location對url匹配;

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

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

  如果不是用正則表達式;可使用=嚴格匹配;

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

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

    1:=前綴的指令嚴格匹配這個查詢;如果找到停止往下匹配

    2:掙下的常規字符串,長的在前,如果這個匹配使用^~前綴,匹配停止;

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

    4:如果第三步產生匹配。則使用這個結果;停止匹配;否則使用第二部的匹配結果;

四個案例:

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

 


免責聲明!

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



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