1. 程式人生 > >Nginx 之四: Nginx服務器的rewrite、全局變量、重定向和防盜鏈相關功能

Nginx 之四: Nginx服務器的rewrite、全局變量、重定向和防盜鏈相關功能

war int 服務器驗證 %u 寫日誌 防盜鏈 循環 版本 算法

一:Nginx 後端服務器組的配置:

1、upstream:

用於設置後端服務器組的主要指令,upstream類似於之前的server塊或http塊,用法如下:

技術分享
upstreame  Myserver{ 
   #ip_hash;
  #least_conn;
  #fair;
  
  #hash $request_uri;
  #hash_method crc32;
  server 192.168.0.2:8080 #weight 2 max_fails 3 fail_timeout 60;   192.168.0.3:8080 backup;   192.168.0.4:8080 down;     } #Myserver是後端服務器組的名稱,在大括號裏面填寫後端服務器的IP和端口信息,默認情況下服務器組被調用以後會使用輪詢調度的方式調用組內的後端服務器。
#keepalived_timeout; #保持的空閑會話的時常,在此時間內客戶端不進行操作,服務器將斷開與客戶端的連接。此數值不能太大,Nginx從1.1.4開始支持。 #ip_hash; 實現會話保持功能,即將某個客戶端的請求定向到組內的同一臺服務器,保證客戶端與服務器之間建立穩定的會話,只有服務器處於無效狀態時,會話才會被轉發給組內其他的服務器。 #server 用於定義一臺後端服務器。 #192.168.0.2:8080 是後端服務器的IP,端口是8080。 #weight = number; #配置權重,與ip_hash有沖突,因為ip_hash是將請求固定在同一個後端服務器的,而weight是根據權重輪訓的,因此不能同時配置在一個upstream內。
#max_fails = number #設置一個失敗的請求次數,在一定時間內超過這個次數就認為服務器是無效的,如可以設置為3。 #在失敗3次以後的60秒將不再將請求分發給失效的server也不在檢查此server的狀態,默認時間是10秒。 #backup; #將一臺服務器標記為備份服務器,只有當所有正常服務器全部不可用的時候才會使用備份的服務器。 #down #將一臺服務器標記為永久不可用的狀態,通常與ip_hash配合使用。
技術分享

2、nginx 的 upstream支持的集中調度算法:

技術分享
1、輪詢(默認) 
   每個請求按時間順序逐一分配到不同的後端服務器,如果後端服務器down掉,能自動刪除。 
2、weight 
   指定輪詢幾率,weight和訪問比率成正比,用於後端服務器性能不均的情況。 
3、ip_hash 
   每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個後端服務器,可以解決session 保持的問題。  
4、fair(第三方) 
   可以依據頁面大小和加載時間長短智能地進行負載均衡,也就是根據後端服務器的響應時間來分配請求,響應時間短的優先分配,Nginx本身默認是不支持fair的,如果需要使用這種調度算法,必須下載Nginx的upstream_fair模塊。
5、url_hash(第三方)
  按訪問url的hash結果來分配請求,使每個url定向到同一個後端服務器,可以進一步提高後端緩存服務器的效率,Nginx本身默認是不支持url_hash的,如果需要這種高度算法,必須安裝Nginx的hash軟件包。
6、least_conn
  根據後端服務器的連接狀況進行分配客戶請求,連接最少的服務器將被有限分配客戶端請求。
技術分享

二:Nginx服務器的rewrite功能介紹:

Nginx服務器利用ngx_http_rewrite_module 模塊解析和處理rewrite請求,所以說此功能依靠 PCRE(perl compatible regularexpression),因此編譯之前要安裝PCRE庫,rewrite功能時nginx服務器的基本功能之一,用於實現URL的重寫,URL的重寫是非常有用的功能,比如它可以在我們改變網站結構之後,不需要客戶端修改原來的書簽,也無需其他網站修改我們的鏈接,就可以設置為訪問,另外還可以在一定程度上提高網站的安全性。

1、地址重寫與地址轉發:

地址重寫和地址轉發是兩個不同的概念,地址重寫是實際上是為了實現址標準化,就像訪問www.baidu.cn可以出現www.baidu.com的首頁,服務器會把www.baidu.cn重寫成www.baidu.com,瀏覽器的地址欄也會顯示www.baidu.com,而轉發指的是將一個域名指向另一個已有站點的過程,地址欄的地址保持不變,因此地址轉發和地址重寫的大致區別如下:

技術分享
地址轉發後客戶端瀏覽器地址欄中的地址顯示是不變的,而地址重寫後地址欄中的地址會變成正確的地址。
在一次地址轉發過程中只會產生一次網絡請求,而一次地址重寫產生兩次請求。
地址轉發一般發生在同一站點項目內,而地址重寫則沒有限制。
地址轉發到的頁面可以不用全路徑名表示,而地址重寫到的頁面必須使用完全的路徑名表示。
地址轉發過程中,可以將客戶端請求的request範圍內的屬性傳遞給新的頁面,但地址重寫不可以。
地址轉發的速度比地址重寫的速度快。
技術分享

2、if指令:

2.1:用於條件判斷,並根據條件判斷結果選擇不同的Nginx配置,可以配置在server或location塊中進行配置,用法如下:

if ($變量) { 
  action
}

註: 如果$變量的值為空字符串或是以0開頭的任意字符串,則if指令認為該條件為false,其他條件為true。

2.2:使用“=”(等於)和“!=”(不等於)比較變量和字符串是否相等,相等時if指令認為該條件為true,反之為false。

if ($request_method = POST) {
      return 405;  
} #條件裏的字符串不需要加引號

2.3:使用正則表達式對變量進行匹配,匹配成功時if指令認為條件為true,否則認為false,變量與表達式之間使用以下符號鏈接:

雙目測試:運算所需變量為兩個的運算符叫做雙目運算符,如下幾個運算符:

~: #表示在匹配過程中區分大小寫字符,(可以通過正則表達式匹配),滿足匹配條件為真,不滿足為假。
~*: #表示在匹配過程中不區分大小寫字符,(可以通過正則表達式匹配),滿足匹配條件為真,不滿足問假。
!~:#區分大小寫不匹配,不滿足為真,滿足為假,不滿足為真。
!~*:#為不區分大小寫不匹配,滿足為假,不滿足為真。

^~ :#如果把這個前綴用於一個常規字符串,那麽告訴nginx 如果路徑匹配那麽不測試正則表達式。

註意:使用~和~!在匹配成功時if指令認為條件為true,匹配失敗為false,使用!~和!~*匹配失敗時if指令認為條件為true,否則為false,在正則表達式中,可以使用小括號對變量進行截取,在大括號中使用$!...$9引用截取的值,如下:

技術分享
if ($http_user_agent ~ MSIE) {  #if語句盡量用在location當中,盡量不要在http或server中使用,會出現莫名的錯誤。
     #判斷客戶端的瀏覽器中是否含有MSIE的字符串,如果包含則為true  
}

#########################################
if ($http_cookie ~* "id="([^;]+)(?:;)") {
    #Nginx配置,可以使用$!和$2獲取截取到的值,如:
     # set $id $1; 將截取到的id的值賦值給$id變量以備後用  
}
註意:整個正則表達式一般不需要加引號,但是如果含有右大括號"}"或者分分號";"的時候,就必須要給整個正則表達式加上引號""
技術分享

3、文件和目錄測試:單目測試,判斷文件或者目錄是否存在

3.1 -f和! -f:判斷請求的文件是否存在和是否不存在

技術分享
-f 表示如果請求的文件存在,則if指令為true,如果請求的文件不存在,則if指令為false。使用! -f的時候,如果請求的文件不存在但是目錄存在,if指令認為條件為true,如果請求的文件和目錄都不存在,則if指令認為條件為false,如果請求的文件存在,也為false,如下:
if (-f $request_filename) {
    #判斷請求的文件是否存在
}

if (! -f $request_filename) {
   #判斷請求的文件是否不存在
}
技術分享

3.2 -d和! -d: #判斷請求的目錄是否存在和是否不存在。

使用-d時,如果請求的目錄存在,則if指令認為條件為true,如果請求的目錄不存在,則認為條件為false,當使用! -d的時候,如果請求的目錄不存在但是目錄的上級存在,if指令認為條件為true,如果該目錄和他的上級都不存在,則為false,如果請求的目錄存在也未false,和of和! -f基本一致。

3.3 -e和! -e: #判斷請求的文件或目錄是否存在和是否不存在。

判斷文件或目錄是否存在,相當於-f和-d的功能合體,當使用-e時,如果請求的文件或目錄存在則if指令認為條件為true,否則為false,當使用! -e時,如果請求的文件或目錄以及該文件的上級都不存在,則為false,否則為true。

3.4 -x和 ! -x: #判斷文件是否可執行和是否不可執行。

使用-x如果文件可執行則返回true,否則為fasle,使用! -x的時候如果文件不可執行返回true,否則為false。

4、break指令:用於中斷當前相同作用域中的其他Nginx配置,與該指令處於同一作用域的Nginx配置中,位於它前面的配置生效,位於後面的指令配置就不再生效了,Nginx服務器在根據配置處理請求的過程中遇到該指令的時候,回到上一層作用域繼續向下讀取配置,該指令可以在server塊和location塊以及if塊中使用,使用語法如下:

location /test {
        root   html;
        index  index.html index.htm;  
     break;  #return之後的將不再執行,之前的可以執行
      }

5、return指令:用於完成對請求的處理,並直接向客戶端返回響應狀態碼,處於此指令後的所有配置都將不被執行,return可以在server、if和location塊進行配置,用法如下:

return (text); #返回給客戶端的響應體內容,可以調用變量
return code; #返回給客戶端HTTP狀態碼,範圍為0-999
return URL; #返回給客戶端的URL地址

註意:從nginx 0.8.42開始,當code使用301時表示永久重定向,302為臨時重定向。303表示當前的響應可以在另一個URL找到,307表示請求的資源臨時從不同的URL響應

6、rewrite指令:通過正則表達式的匹配來改變URI,可以同時存在一個或多個指令,按照順序依次對URI進行匹配。

技術分享
URI(universal resource identifier):通用資源標識符,用於對網絡中各種資源進行標示,有存放資源的主機名、片段標識符和相對URL三部分組成,存放資源的主機名一把由傳輸協議(scheme)、主機和資源路徑三部分組成,片段標識符執行資源內容的具體元素,相對URL標示主機上的相對路徑,一般格式為:scheme:[//] [[用戶名[:密碼]@]主機名:[端口號]][/資源路徑名],如http://www.a.com:8080/path/file/index.html,Nginx就是對其中的URI /path/file這部分進行處理和匹配,但是不能處理http://www.a.com,因為Nginx接受到的URL不包含http://www.a.com。
URL(uniform resource location):統一資源定位符,是用於在Internet中描述資源的字符串,是URL的子集,主要包括傳世協議(scheme)、主機(IP、端口號或者域名)和資源具體地址(目錄和文件名)等三部分,一般格式為 scheme://主機名[:端口號][/資源路徑],如:http://www.a.com:8080/path/file/index.html就是一個URL路徑
URI就是一種資源定位機制,它是比較籠統地定位了資源,並不局限於客戶端和服務器,而URL就定位了網上的一切資源,只要是網上的資源,都有唯一的URL。
技術分享

註:rewrite指令接收到的URI為 /path/file,不包含參數,如/path/file/arg1=value1&argv2=value2,只會接收到/path/file,不包含arg1=value1&argv2=value2,但是我們可以使用nginx內置的全局變量$request_uri來匹配用戶的uri,在$request_uri後面要添加問號,replacement支持nginx全局變量的使用,常用的還要$uri和$args等,如:

rewrite www.a.com  http://www.b.com$request_uri? permanent;

註意:replacement是匹配成功後用於替換URL中被截取內容的字符串,默認情況下,如果該字符串是有http://或者https://開頭的,則不會繼續向下進行其他處理,而且直接將重寫後的URL返回給客戶端。

7、flag:用來設置rewrite對URI處理的行為或動作,可以為一下四個當中的一個:

7.1、last:終止繼續在本location塊中處理接受到的URL,並將在本location中重新的URL作為一個新的URL,繼續使用後面的各location塊進行處理,該標誌將重寫後的URL重新再server塊中執行,為重寫後的URI轉入到其他location塊並繼續處理的機制,nginx服務器的last處理超過10次循環之後將返回錯誤代碼500,使用方法如下:

location / {
    rewrite ^(/test/.*)/msie(.*)\..*$  $1/test/mp3/$2.html break;
    rewrite ^(/test/.*)/other(.*)\.*$ $1/test/other/$2.html break;    
}

註:如果URI在第二行被匹配成功並處理,Nginx服務器不會繼續使用第三行的配置和匹配處理新的URL,而是讓所有的location快重新匹配和處理新的URI,即一旦在本location中匹配成功一行,就跳出本location並在下一個location匹配,直到在下一個location匹配成功後再跳出下一個location繼續下下一個,直到最後一個為止。

7.3、break:將你的URI作為一個新的URI,在本快中繼續進行處理,該標誌將重寫後的地址在當前的location快中執行,不會將新的URI轉向其他的location模塊,如下:

技術分享
註意:如果第二行被匹配並處理成功,Nginx服務器將新的URI繼續在本location塊中使用第三行匹配和處理,新的URI始終在一個location之內匹配和處理,直到本location最後一個匹配條件。last一般寫在server和if中,而break一般使用在location中
1、last一般寫在server和if中,而break一般使用在location中
2、last不終止重寫後的url匹配,即新的url會再從server走一遍匹配流程,而break終止重寫後的匹配
3、break和last都會繼續執行後面的rewrite指令,只是last會終止本location的匹配跳轉到其他location,而break只會在當前location繼續匹配,直到最後一條匹配結果為止,不會跳轉到其他location。
技術分享

7.4、redirect:將重寫後的URI返回給客戶端,狀態碼為302,指明是臨時重定向URI,主要用在replacement變量不是以http或https開頭的情況下。

7.5、permanent:將重寫後的URI返回給客戶端,代碼為301,註明是永久重定向。

註意:在使用flag的時候,

8、rewrite_log:用於配置是否開啟URL重寫日誌的輸出功能,用法如下:

rewrite_log on|off; #默認為off。,如果設置為開啟,URL的相關日誌將以notice級別的輸出到error_log配置的文件當中。

9、set:用於設置一個新的變量,其用法結構為:

set  variable value;  #variable為變量的名稱,要使用$作為變量的第一個字符,且變量名不能與nginx服務器預設的全局變量相同
value:為變量的值,可以是字符串、其他變量和變量組合等。

10、uninitialized_variable_warn:用於配置使用未初始化的變量時,是否記錄告警日誌,用法如下:

uninitialized_variable_warn on|off;

4、root和alias:

root:指定web的家目錄,在定義location的時候,文件的絕對路徑等於 root+location,如:

location /bbs {
        root   html;  #必須要在html目錄中創建一個bbs目錄才可以訪問,否則報錯。
        index  index.html;
        }

alias:定義路徑別名,會把訪問的路徑重新定義到其指定的路徑,如:

 location /newweb { #當訪問newweb的時候,會顯示alias定義的 /usr/local/nginx/html/newweb/裏面的內容。
        alias  /usr/local/nginx/html/newweb/;
        }

註:alias後面必須要用“/”結束,否則會找不到文件,而root要結合location,要麽都有/,要麽都沒有/,如果一個有一個沒有在訪問的時候會出錯。

三、Rewrite常用的全局變量:

1.Nginx服務器內置了很多預先定義好的內置變量,就要方便獲取很多相關的服務器信息以及與請求相關的指令、參數當信息,可以更加方便的用戶進行自定義的功能定義等,具體變量如下如下:

1.1、$args:變量中存放了URL中的指令,比如http://mobile.weathercn.com/index.do?id=101290101&partner=中的id=101290101&partner=,而且可以有多個指令。

1.2、$content_length:保存了請求報文頭部中的content-lenght字段。

1.3、$content_type:保存了請求頭部中的content-type字段。

1.4、$document_root:保存了針對當前資源的請求的系統根目錄。如:

技術分享

1.5、$document_uri:保存了當前請求中不包含指令的URI,主註意是不包含請求的指令,比如http://hfnginx.chinacloudapp.cn/index.do?id=101060101&partner=會被定義為/index.do。

1.6、$host:存放了請求的服務器名稱。

1.7、$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的瀏覽器信息

1.8、$http_cookie:客戶端的cookie信息。

1.9、$limit_rate:如果nginx服務器使用limit_rate配置了顯示網絡速率,則會顯示,如果沒有設置, 則顯示0。

1.2.0:$remote_addr:存放了客戶端的地址,註意是客戶端的公網IP,也就是一家人訪問一個網站,則會顯示為路由器的公網IP,如下:

技術分享

1.2.1:$remote_port:客戶端請求Nginx服務器時隨機打開的端口,這是每個客戶端自己的端口。

1.2.2:$remote_user:已經經過Auth Basic Module驗證的用戶名。

1.2.3:$request_body_file:做反向代理時發給後端服務器的本地資源的名稱。

1.2.4:$request_method:請求資源的方式,GET/PUT/DELETE等

1.2.5:$request_filename:當前請求的資源文件的路徑名稱,由root或alias指令與URI請求生成。

/usr/local/nginx//html/web/

1.2.6:$request_uri:包含請求參數的原始URI,不包含主機名,如:”/index.do?id=101020100&partner=”。

/web/

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

1.2.8:$scheme:請求的協議,如ftp,https,http等。

1.2.9:$server_protocpl:保存了客戶端請求資源使用的協議的版本,如HTTP/1.0,HTTP/1.1,HTTP/2.0等。

1.3.0:$server_addr:保存了服務器的IP地址。

192.168.0.24

1.3.1:$server_name:服務器的主機名。

hfnginx.chinacloudapp.cn

1.3.2:$server_port:服務器的端口號。

80

1.3.3:$uri:與$document_uri相同,是一個不包含指令的uri地址。

如訪問:hfnginx.chinacloudapp.cn/index.do?id=101020100&partner=,uri如下:
/index.do

四:rewrite 功能的具體使用:

nginx rewrite功能使用模塊ngx_http_rewrite_module,rewrite是nginx服務器的重要模塊之一,它一方面實現了URL的重寫功能,另一方面為Nginx服務器提供反向代理服務器的支持,使用如下:

1、proxy_pass:反向代理,將用戶的請求代理至後端服務器:

技術分享
server {
        server_name  hfnginx.chinacloudapp.cn;
        #access_log  logs/host.access.log  main;
        location / {
            root   html/hfnginx;
            index  index.html index.htm;
        }
        location /form/ {  #匹配一個訪問的目錄
            proxy_pass  http://192.168.0.201/bbs/;  #/form後面的斜杠要和http://192.168.0.201/bbs後面的斜杠要麽都有要麽都沒有,否則訪問匹配會出現錯誤。
  } }
技術分享

1.1訪問結果:

技術分享

1.2訪問過程第一次是一個301(頁面永久重定向)如下:

技術分享

1.3訪問過程第二次,返回頁面的內容:

技術分享

2.使用正則匹配訪問頁面:

技術分享
server {
        server_name  hfnginx.chinacloudapp.cn;
        #access_log  logs/host.access.log  main;
        location / {
            root   html/hfnginx;
            index  index.html index.htm;
        }
        location ~* ^/form {
            proxy_pass  http://192.168.0.201;  #使用正則的話,http://192.168.0.201後面不支持加目錄,否則語法錯誤,後端服務器Web的目錄要和location設置的/form同名,否則報404頁面找不到錯誤。 
} }
技術分享

2.1:後端服務器的web目錄:

[root@Server1 html]# ls
bbs
[root@Server1 html]# mv bbs form #將上一個例子中的bbs目錄重命名成form,form對應locati的名稱
[root@Server1 html]# ls
form

2.2:訪問測試,步驟也是兩次,一次301,一次正常頁面:

技術分享

2.3:配置Nginx轉發客戶端IP:

        location ~* ^/form {
            proxy_pass  http://192.168.0.201;
            proxy_set_header X-Real-IP $remote_addr;
        }

2.4:http默認無法記錄這個變量,因此要手動設置apache的日誌格式:

[root@Server1 httpd]# vim /etc/httpd/conf/httpd.conf 
更改配置文件中日誌格式的一行:
LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined #%{X-Real-IP}i表示是頭部報文中某個變量的值,i是取值,取得是報文中X-Real-IP對應的值。這個值就是客戶端的真實IP

2.5:重新訪問並查看apache日誌:

[root@Server1 httpd]# tail -n 1 /var/log/httpd/access_log 
47.88.87.169 - - [07/May/2016:19:39:43 +0800] "GET /form/ HTTP/1.0" 200 38 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.86 Safari/537.36"

五:臨時重定向與永久重定向:

1.防盜鏈:

referer是記錄打開一個頁面之前記錄是從哪個頁面跳轉過來的,如果別人只鏈接了自己網站圖片或某個單獨的資源,而不是網站的頁面,這就是盜鏈,

location /image {
            valid_referers none blocked www.baidu.com;
    if ($invalid_referer) {
          return 403;
} #none是用戶正常在瀏覽器輸入地址訪問的請求連接 #blocked 類似於防火墻法則,只要不符合給定條件的就認定是不合法的,就拒絕訪問。

2.通過rewrite完成地址重寫:

301:永久重定向,一般資源都在服務器內部,客戶端請求一次即可完成數據的返回。

302:臨時重定向,當nginx作為代理服務器,並使用rewrite重寫用戶請求的URL的到其他服務器的時候,就是臨時重定向。

技術分享
server {
        server_name  hfnginx.chinacloudapp.cn;
        location / {
            root   html;  #定義存放web的目錄
            index  index.html;
            #rewrite ^/bbs/(.*)$  http://www.weather.com.cn/$1;  #將請求轉發給其他服務器處理,是臨時重定向,客戶端需要在服務器返回報文中頭部中查找到location字段並根據其中的路徑到新服務器發送請求。
            rewrite ^/bbs/(.*)$   /web/$1;  #/web是在html目錄下,也就是這裏的跟就是html目錄,將請求在服務器內存處理並返回給用戶,是永久重定向的方式
        } 
}
技術分享

2.1臨時重定向請求過程如下:

技術分享

2.2:永久重定向如下:

技術分享

六:rewrite後面的四個flag:

1.last:本次重寫完成之後,重啟下一輪檢查,大多數情況下使用last,但是如果匹配寫的有問題,會導致出現循環匹配,直到十次之後出錯。

2.break:本次完成重寫之後,直接執行後續數據操作,不再進行其他的條件匹配,在非跟location使用rewrite匹配的時候要使用break,避免導致循環。

3.redirect:返回302臨時重定向,如果替換字段用http://開頭則被使用。

4.permanent:返回301永久重定向。

七:對Apache實現上傳下載分離:

1.確認模塊當中有dav模塊:

LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
LoadModule dav_lock_module modules/mod_dav_lock.so

2、打開dav功能:

<Directory "/var/www/html">
Dav on #加一行

3、重啟httpd:

[root@Server1 html]# systemctl  restart  httpd

4、將www目錄改為apache權限,並使用curl -T命令測試上傳:

技術分享
[root@Server1 html]# chown  apache:apache /var/www/html/ -R  #更改屬主屬組
[root@Server1 html]# curl -T  /etc/issue http://192.168.0.202  #上傳一個文件
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>201 Created</title>
</head><body>
<h1>Created</h1>
<p>Resource /issue has been created.</p>  #返回上傳成功
</body></html>

驗證:

 [root@Server1 html]# ls /var/www/html/
form index.html issue

技術分享

5、客戶端使用瀏覽器訪問測試:
技術分享

6、通過Nginx實現下載和上傳的分離:

技術分享
server {
        server_name  hfnginx.chinacloudapp.cn;
        location / {
            #root   html;
            index  index.html;
            proxy_pass  http://192.168.0.201;
            if ($request_method = "PUT"){  #假如請求的方法是上傳
                proxy_pass  http://192.168.0.202;
                }
        }
}
技術分享

7、測試上傳是否生效:

技術分享

8、服務器驗證上傳的文件:

技術分享

八:幾個代表性的例子:

1.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
技術分享

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;
} 
技術分享

3、關於防盜鏈:

技術分享
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是本公司的域名,要允許訪問於是要先允許本機的訪問,再禁止其他服務器的訪問
技術分享

4.實際使用建議:

技術分享
實際使用中,個人覺得至少有三個匹配規則定義,如下:
#直接匹配網站根,通過域名訪問網站首頁比較頻繁,使用這個會加速處理,官網如是說。
#這裏是直接轉發給後端應用服務器了,也可以是一個靜態首頁
# 第一個必選規則
location = / {
    proxy_pass http://tomcat:8080/index
}
# 第二個必選規則是處理靜態文件請求,這是nginx作為http服務器的強項
# 有兩種配置模式,目錄匹配或後綴匹配,任選其一或搭配使用
location ^~ /static/ {
    root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
    root /webroot/res/;
}
#第三個規則就是通用規則,用來轉發動態請求到後端應用服務器
#非靜態文件請求就默認是動態請求,自己根據實際把握
#畢竟目前的一些框架的流行,帶.php,.jsp後綴的情況很少了
location / {
    proxy_pass http://tomcat:8080/
}

如果其他可以精確匹配的路徑,也可以精確匹配,這樣會加快Nginx處理請求。
技術分享

5、常用的正則匹配:

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

6、根據圖片尺寸rewrite請求鏈接:

rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;
#將/images/bla_500x400.jpg的文件請求,重寫到/resizer/bla.jpg?width=500&height=400地址,並會繼續嘗試匹配location。

7、域名重寫:

技術分享
server {
        server_name  hfnginx.chinacloudapp.cn; #凡是訪問hfnginx.chinacloudapp.cn都會重定向到http://www.baidu.com
        location / {
        root   html;
        index  index.html;
        rewrite  ^/  http://www.baidu.com;
    } 
}
技術分享

8、完整的例子引用:

技術分享
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";
        }
}
技術分享

Nginx 之四: Nginx服務器的rewrite、全局變量、重定向和防盜鏈相關功能