天天看點

Nginx Location文法和Rewrite文法(學習筆記七)

1 Location文法規則

1.1 Location規則

文法規則: location [=|~|~*|^~] /uri/ {… }

首先比對 =,其次比對^~,其次是按檔案中順序的正則比對,最後是交給 /通用比對。當有比對成功時候,停止比對,按目前比對規則處理請求。

符号含義

== 開頭表示精确比對

^~^~開頭表示uri以某個正常字元串開頭,了解為比對 url路徑即可。nginx不對url做編碼,是以請求為/static/20%/aa,可以被規則^~ /static/ /aa比對到(注意是空格)

~~ 開頭表示區分大小寫的正則比對

~*~* 開頭表示不區分大小寫的正則比對

!~和!~*!~和!~*分别為區分大小寫不比對及不區分大小寫不比對的正則

/使用者所使用的代理(一般為浏覽器)

$http_x_forwarded_for可以記錄用戶端IP,通過代理伺服器來記錄用戶端的ip位址

$http_referer可以記錄使用者是從哪個連結通路過來的

  比對規則示例:

      location = / {

          #規則A

      }

      location = /login {

          #規則B

      location ^~ /static/ {

          #規則C

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

          #規則D

      location ~* \.png$ {

          #規則E

      location !~ \.xhtml$ {

          #規則F

      location !~* \.xhtml$ {

          #規則G

      location / {

          #規則H

那麼産生的效果如下:

1. 通路根目錄/,比如http://localhost/将比對規則A

2. 通路 http://localhost/login 将比對規則B,http://localhost/register則比對規則H

3. 通路 http://localhost/static/a.html 将比對規則C

4. 通路 http://localhost/a.gif,http://localhost/b.jpg 将比對規則D和規則E,但是規則D順序優先,規則E不起作用,而http://localhost/static/c.png則優先比對到規則C

5. 通路 http://localhost/a.PNG 則比對規則E,而不會比對規則D,因為規則E不區分大小寫。

6. 通路 http://localhost/a.xhtml 不會比對規則F和規則G,http://localhost/a.XHTML不會比對規則G,因為不區分大小寫。規則F,規則G屬于排除法,符合比對規則但是不會比對到,是以想想看實際應用中哪裡會用到。

7. 通路 http://localhost/category/id/1111 則最終比對到規則H,因為以上規則都不比對,這個時候應該是nginx轉發請求給後端應用伺服器,比如FastCGI(

PHP

),tomcat(jsp),nginx作為方向代理伺服器存在。

1.2 實際常用規則

#直接比對網站根,通過域名通路網站首頁比較頻繁,使用這個會加速處理。

#這裡是直接轉發給後端應用伺服器了,也可以是一個靜态首頁

# 第一個必選規則

    location = / {

      proxy_passhttp://tomcat:8080/index

    }

# 第二個必選規則是處理靜态檔案請求,這是nginx作為http伺服器的強項

# 有兩種配置模式,目錄比對或字尾比對,任選其一或搭配使用

    location ^~ /static/ {

      # 請求/static/a.txt 将被映射到實際目錄檔案:/webroot/res/static/a.txt

      root /webroot/res/;

    location ~* \.(gif|jpg|jpeg|png|css|js|ico)${

第三個規則就是通用規則,用來轉發動态請求到後端應用伺服器

#非靜态檔案請求就預設是動态請求,自己根據實際把握

#畢竟目前的一些架構的流行,帶.php,.jsp字尾的情況很少了

    location / {

      proxy_pass http://tomcat:8080/

1.3 Location解析過程

Nginx Location文法和Rewrite文法(學習筆記七)

總結:

1、    先判斷精準命中,如果命中,立即傳回結果并結束解析過程。

2、    判斷普通命中,如果有多個命中,“記錄”下來“最長”的命中結果(記錄但不結束,最長的為準)。

3、    繼續判斷正規表達式的解析結果,按配置裡的正規表達式順序為準,由上至下開始比對,一旦比對成功1個,立即傳回結果,并結束解析過程。

4、    普通命中順序無所謂,是因為按命中的長短來确定。正則命中,順序有所謂,因為是從前入往後命中的。

2 ReWrite文法

Nginx提供的全局變量或自己設定的變量,結合正規表達式和标志位實作url重寫以及重定向。

rewrite隻能放在server{},location{},if{}中,

并且隻能對域名後邊的除去傳遞的參數外的字元串起作用。

Rewrite主要的功能就是實作URL的重寫,Nginx的Rewrite規則采用Pcre,perl相容正規表達式的文法規則比對,如果需要Nginx的Rewrite功能,在編譯Nginx之前,需要編譯安裝PCRE庫。

通過Rewrite規則,可以實作規範的URL、根據變量來做URL轉向及選擇配置。

2.1 ReWrite相關指令

指令預設值使用範圍作用

breaknoneif,server,location完成目前的規則集,不再處理rewrite指令,需要和last加以區分

if ( condition )

{ ... }

noneserver,location用于檢測一個條件是否符合,符合則執行大括号内的語句。不支援嵌套,不支援多個條件&&或||處理

returnnoneserver,if,location用于結束規則的執行和傳回狀态碼給用戶端。狀态碼的值可以是:204,400,402~406,408,410,411,413,416以及500~504,另外非标準狀态碼444,表示以不發送任何的Header頭來結束連接配接。

rewrite regex replacement flag server,location,if該指令根據表達式來重定向URI,或者修改字元串。指令根據配置檔案中的順序來執行。注意重寫表達式隻對相對路徑有效。

uninitialized_variable_warn on|offonhttp,server,location,if該指令用于開啟和關閉未初始化變量的警告資訊,預設值為開啟。

set  variable  valuenone 該指令用于定義一個變量,并且給變量進行指派。變量的值可以是文本、一個變量或者變量和文本的聯合,文本需要用引号引起來。

2.2 Rewrite全局變量

rewrite全局變量表

變量含義

$args這個變量等于請求行中的參數,同$query_string

$content length請求頭中的Content-length字段。

$content_type請求頭中的Content-Type字段。

$document_root目前請求在root指令中指定的值。

$host請求主機頭字段,否則為伺服器名稱。

$http_user_agent用戶端agent資訊

$http_cookie用戶端cookie資訊

$limit_rate這個變量可以限制連接配接速率。

$request_method用戶端請求的動作,通常為GET或POST。

$remote_addr用戶端的IP位址。

$remote_port用戶端的端口。

$remote_user已經經過Auth Basic Module驗證的使用者名。

$request_filename目前請求的檔案路徑,由root或alias指令與URI請求生成。

$schemeHTTP方法(如http,https)。

$server_protocol請求使用的協定,通常是HTTP/1.0或HTTP/1.1。

$server_addr伺服器位址,在完成一次系統調用後可以确定這個值。

$server_name伺服器名稱。

$server_port請求到達伺服器的端口号。

$request_uri包含請求參數的原始URI,不包含主機名,如”/foo/bar.php?arg=baz”。

$uri不帶請求參數的目前URI,$uri不包含主機名,如”/foo/bar.html”。

$document_uri與$uri相同。

2.3 Rewrite文法規則

操作符含義

= ,!=比較的一個變量和字元串。

~, ~*與正規表達式比對的變量,如果這個正規表達式中包含},;則整個表達式需要用"或'包圍。

-f,!-f檢查一個檔案是否存在。

-d, !-d檢查一個目錄是否存在。

-e,!-e檢查一個檔案、目錄、符号連結是否存在。

-x, !-x檢查一個檔案是否可執行。

2.4 if指令

    if  文法格式

    if 空格 (條件) {

        重寫模式

    }

        # 限制浏覽器通路

    if ($http_user_agent ~ Firefox) {

      rewrite ^(.*)$ /firefox/$1 break;

    }     

    if ($http_user_agent ~ MSIE) {

        rewrite ^(.*)$ /msie/$1 break;

    if ($http_user_agent ~ Chrome) {

        rewrite ^(.*)$ /chrome/$1 break;

2.5 return指令

    # 限制IP通路

    if  ($remote_addr = 192.168.197.142) {

      return 403;

1.首先從日志查出ip

Nginx Location文法和Rewrite文法(學習筆記七)

修改conf配置檔案

Nginx Location文法和Rewrite文法(學習筆記七)

重新開機配置檔案通路發現

Nginx Location文法和Rewrite文法(學習筆記七)

2.6 rewrite指令

#判斷目錄是否存在

#伺服器内部的rewrite和302跳轉不一樣.跳轉的話URL都變了,變成重新http請求index.html,而内部rewrite,上下文沒變。

    if (!-e $document_root$fastcgi_script_name) {

        rewrite ^.*$ /index.html break;

2.7 set指令

# set指令是設定變量用的,可以用來達到多條件判斷時作标志用

#判斷IE并重寫,且不用break;我們用set變量來達到目的

    if ($http_user_agent ~* msie) {

        set $isie 1;

    if ($fastcgi_script_name = ie.html) {

        set $isie 0;

    if ($isie 1) {

        rewrite ^.*$ ie.html;

常用例子

(1)表示通路路徑有a,b,c,d都跳轉到//127.0.0.1:8080$Request_uri

        location ~^/(a|b|c|d){

            proxy_pass http://127.0.0.1:8080$Request_uri;

            client_max_body_size  10240k;

            client_body_buffer_size  128k;

        }

繼續閱讀