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解析過程
總結:
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
修改conf配置檔案
重新開機配置檔案通路發現
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;
}