1. 程式人生 > 其它 >Nginx轉發匹配規則

Nginx轉發匹配規則

一、正則表示式匹配

  1. ~ 為區分大小寫匹配
  2. ~* 為不區分大小寫匹配
  3. !~!~* 分別為區分大小寫不匹配及不區分大小寫不匹配

二、檔案及目錄匹配

  1. -f!-f 用來判斷是否存在檔案
  2. -d!-d 用來判斷是否存在目錄
  3. -e!-e 用來判斷是否存在檔案或目錄
  4. -x!-x 用來判斷檔案是否可執行

三.rewrite指令的最後一項引數為flag標記,flag標記有

  1. last 相當於 apache 裡面的[L]標記,表示 rewrite
  2. break 本條規則匹配完成後,終止匹配,不再匹配後面的規則。
  3. redirect 返回302臨時重定向,瀏覽器地址會顯示跳轉後的URL地址。
  4. permanent 返回301永久重定向,瀏覽器地址會顯示跳轉後的URL地址。

使用 lastbreak 實現URI重寫,瀏覽器位址列不變。
而且兩者有細微差別,使用alias指令必須用 last標記;使用proxy_pass指令時,需要使用break標記。Last標記在本條rewrite規則執行完畢後,會對其所在server{......}標籤重新發起請求,而break標記則在本條規則匹配完成後,終止匹配。
例如:如果我們將類似URL/photo/123456 重定向到 /path/to/photo/12/1234/123456.png
rewrite "/photo/([0-9]{2})([0-9]{2})([0-9]{2})" rewrite "/path/to/photo/$1/$1$2/$1$2$3.png" ;
四、NginxRewrite

規則相關指令
1、break指令
使用環境:serverlocationif
該指令的作用是完成當前的規則集,不再處理rewrite指令。
2、if 指令
使用環境:serverlocation
該指令用於檢查一個條件是否符合,如果條件符合,則執行大括號內的語句。If指令不支援巢狀,不支援多個條件&&和||處理。
3、return指令
語法:returncode
使用環境:serverlocationif
該指令用於結束規則的執行並返回狀態碼給客戶端。
示例:如果訪問的URL以".sh"或".bash"結尾,則返回403狀態碼
location ~ .*\.(sh|bash)?$ { return 403; }
4、rewrite 指令

語法:rewriteregex replacement flag
使用環境:serverlocationif
該指令根據表示式來重定向URI,或者修改字串。指令根據配置檔案中的順序來執行。注意重寫表示式只對相對路徑有效。如果你想配對主機名,你應該使用if語句,示例如下:
if( $host ~* www\.(.*) ) { set $host_without_www $1; rewrite ^(.*)$ http://$host_without_www$1permanent; }
5、Set指令
語法:setvariable value ; 預設值:none 使用環境:serverlocationif
該指令用於定義一個變數,並給變數賦值。變數的值可以為文字、變數以及文字變數的聯合。
set$varname "hello world";
6、Uninitialized_variable_warn指令
語法:uninitialized_variable_warnon|off
使用環境:httpserverlocationif
該指令用於開啟和關閉未初始化變數的警告資訊,預設值為開啟。
五.Nginx的Rewrite規則編寫例項
1、當訪問的檔案和目錄不存在時,重定向到某個html檔案
if( !-e $request_filename ) { rewrite ^/(.*)$ index.htmllast; }
2、目錄對換 /123456/xxxx ====> /xxxx?id=123456
rewrite ^/(\d+)/(.+)/ /$2?id=$1 last;
3、如果客戶端使用的是IE瀏覽器,則重定向到/ie目錄下
if( $http_user_agent ~ MSIE) { rewrite ^(.*)$ /ie/$1 break; }
4、禁止訪問多個目錄
location ~ ^/(cron|templates)/ { deny all; break; }
5、禁止訪問以/data開頭的檔案
location ~ ^/data { deny all; }
6、禁止訪問以.sh,.flv,.mp3為檔案字尾名的檔案
location ~ .*\.(sh|flv|mp3)$ { return 403; }
7、設定某些型別檔案的瀏覽器快取時間
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } location ~ .*\.(js|css)$ { expires 1h; }
8、給favicon.ico和robots.txt設定過期時間
這裡為favicon.ico為99天,robots.txt為7天並不記錄404錯誤日誌
location ~(favicon.ico) { log_not_found off; expires 99d; break; } location ~(robots.txt) { log_not_found off; expires 7d; break; }
9、設定某個檔案的過期時間;這裡為600秒,並不記錄訪問日誌
location ^~ /html/scripts/loadhead_1.js { access_log off; root /opt/lampp/htdocs/web; expires 600; break; }
10、檔案反盜鏈並設定過期時間
這裡的return412 為自定義的http狀態碼,預設為403,方便找出正確的盜鏈的請求
rewrite ^/ http: //顯示一張防盜鏈圖片 access_log off; //不記錄訪問日誌,減輕壓力 expires 3d //所有檔案3天的瀏覽器快取 location ~*^.+\.(jpg|jpeg|gif|png|swf|rar|zip|css|js)$ { valid_referers none blocked *.*. localhost 208.97.167.194; if ($invalid_referer) { rewrite ^/ return 412; break; } access_log off; root /opt/lampp/htdocs/web; expires 3d; break; }
11、只允許固定ip訪問網站,並加上密碼
root /opt/htdocs/www; allow 208.97.167.194; allow 222.33.1.2; allow 231.152.49.4; deny all; auth_basic “C1G_ADMIN”; auth_basic_user_file htpasswd;
12、將多級目錄下的檔案轉成一個檔案,增強seo效果
/job-123-456-789.html 指向/job/123/456/789.html rewrite^/job-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /job/$1/$2/jobshow_$3.html last;
13、檔案和目錄不存在的時候重定向:
if (!-e $request_filename) { proxy_pass http://127.0.0.1; }
14、將根目錄下某個資料夾指向2級目錄
如/shanghaijob/ 指向 /area/shanghai/ 如果你將last改成permanent,那麼瀏覽器位址列顯是/location/shanghai/ rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2last; 上面例子有個問題是訪問/shanghai時將不會匹配 rewrite ^/([0-9a-z]+)job$ /area/$1/ last; rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2last; 這樣/shanghai 也可以訪問了,但頁面中的相對連結無法使用, 如./list_1.html真實地址是/area/shanghia/list_1.html會變成/list_1.html,導至無法訪問。 那我加上自動跳轉也是不行咯 (-d $request_filename)它有個條件是必需為真實目錄,而我的rewrite不是的,所以沒有效果 if (-d $request_filename){ rewrite ^/(.*)([^/])$ http://$host/$1$2/permanent; } 知道原因後就好辦了,讓我手動跳轉吧 rewrite ^/([0-9a-z]+)job$ /$1job/permanent; rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2last;
15、域名跳轉
server{ listen 80; server_name jump.linuxidc.com; index index.html index.htm index.php; root /opt/lampp/htdocs/www; rewrite ^/ access_log off; }
16、多域名轉向
server_name www.linuxidc.comwww.linuxidc.net; index index.html index.htm index.php; root /opt/lampp/htdocs; if ($host ~ "linuxidc\.net") { rewrite ^(.*) $1permanent; }
六、nginx全域性變數
arg_PARAMETER #這個變數包含GET請求中,如果有變數PARAMETER時的值。 args #這個變數等於請求行中(GET請求)的引數,如:foo=123&bar=blahblah; binary_remote_addr #二進位制的客戶地址。 body_bytes_sent #響應時送出的body位元組數數量。即使連線中斷,這個資料也是精確的。 content_length #請求頭中的Content-length欄位。 content_type #請求頭中的Content-Type欄位。 cookie_COOKIE #cookie COOKIE變數的值 document_root #當前請求在root指令中指定的值。 document_uri #與uri相同。 host #請求主機頭欄位,否則為伺服器名稱。 hostname #Set to themachine’s hostname as returned by gethostname http_HEADER is_args #如果有args引數,這個變數等於”?”,否則等於”",空值。 http_user_agent #客戶端agent資訊 http_cookie #客戶端cookie資訊 limit_rate #這個變數可以限制連線速率。 query_string #與args相同。 request_body_file #客戶端請求主體資訊的臨時檔名。 request_method #客戶端請求的動作,通常為GET或POST。 remote_addr #客戶端的IP地址。 remote_port #客戶端的埠。 remote_user #已經經過Auth Basic Module驗證的使用者名稱。 request_completion #如果請求結束,設定為OK. 當請求未結束或如果該請求不是請求鏈串的最後一個時,為空(Empty)。 request_method #GET或POST request_filename #當前請求的檔案路徑,由root或alias指令與URI請求生成。 request_uri #包含請求引數的原始URI,不包含主機名,如:”/foo/bar.php?arg=baz”。不能修改。 scheme #HTTP方法(如http,https)。 server_protocol #請求使用的協議,通常是HTTP/1.0或HTTP/1.1。 server_addr #伺服器地址,在完成一次系統呼叫後可以確定這個值。 server_name #伺服器名稱。 server_port #請求到達伺服器的埠號。
#### 七、Apache和Nginx規則的對應關係
Apache的RewriteCond對應Nginx的if Apache的RewriteRule對應Nginx的rewrite Apache的[R]對應Nginx的redirect Apache的[P]對應Nginx的last Apache的[R,L]對應Nginx的redirect Apache的[P,L]對應Nginx的last Apache的[PT,L]對應Nginx的last 複製程式碼
例如:允許指定的域名訪問本站,其他的域名一律轉向
Apache: RewriteCond %{HTTP_HOST} !^(.*?)\.aaa\.com$[NC] RewriteCond %{HTTP_HOST} !^localhost$ RewriteCond %{HTTP_HOST}!^192\.168\.0\.(.*?)$ RewriteRule ^/(.*)$ [R,L]
Nginx過濾示例:
if( $host ~* ^(.*)\.aaa\.com$ ) { set $allowHost ‘1’; } if( $host ~* ^localhost ) { set $allowHost ‘1’; } if( $host ~* ^192\.168\.1\.(.*?)$ ) { set $allowHost ‘1’; } if( $allowHost !~ ‘1’ ) { rewrite ^/(.*)$ ; }
總結
後端開發是一個最接近全棧的一個職業,前端不夠用後端頂上寫頁面JS,沒有運維不要緊後端來維護伺服器,總之一個好的後端就是能面面俱到。