Nginx實現IF語句裡的AND,OR多重判斷

pythontab發表於2018-07-01


一、Nginx Rewrite規則相關指令有if、rewrite、set、return、break等


1.其中rewrite是最關鍵的指令。一個簡單的Nginx Rewrite規則語法如下:

rewrite ^/b/(.*)\.html /play.php?video=$1 last;

break;


2.如果加上if語句,示例如下:

if (!-f $request_filename )

rewrite ^/img/(.*)$ /site/$host/images/$1 last;


二、Nginx與Apache的Rewrite規則例項對比


簡單的Nginx和Apache 重寫規則區別不大,基本上能夠完全相容。例如:


Apache Rewrite 規則:

RewriteRule ^/(mianshi|xianjing)/$ /zl/index.php?name=$1 [L]

RewriteRule ^/ceshi/$ /zl/ceshi.php [L]

RewriteRule ^/(mianshi)_([a-zA-Z]+)/$ /zl/index.php?name=$1_$2 [L]

RewriteRule ^/pingce([0-9]*)/$ /zl/pingce.php?id=$1 [L]


Nginx Rewrite 規則:

rewrite ^/(mianshi|xianjing)/$ /zl/index.php?name=$1 last;

rewrite ^/ceshi/$ /zl/ceshi.php last;

rewrite ^/(mianshi)_([a-zA-Z]+)/$ /zl/index.php?name=$1_$2 last;

rewrite ^/pingce([0-9]*)/$ /zl/pingce.php?id=$1 last;


三、NGINX實現IF語句裡的AND,OR多重判斷

1.nginx的配置中不支援if條件的邏輯與/邏輯或運算 ,並且不支援if的巢狀語法,我們可以用變數的方式來實現:


具體方法為AND 就用變數疊加,OR就用0或1切換。


1)首先是虛擬碼(即不被nginx支援)寫在這裡只是為了方便理解:

if ($remote_addr ~ "^(12.34|56.78)" && $http_user_agent ~* "spider") {

return 403;

}


這是等效的,並真實可用的配置

set $flag 0;
if ($remote_addr ~ "^(12.34|56.78)") {
  set $flag "${flag}1";
}
if ($http_user_agent ~* "spider") {
  set $flag "${flag}2";
}
if ($flag = "012") {
  return 403;
}


2)伺服器真實生效的配置

location / {
if ( $request_filename ~ ^(.+)/(.+)$ ) {
   set $l2 $1;
}
set $ll $request_filename;
if ( !-e $request_filename ) {
   set $l3 "3";
}
if ( !-e $l2 ) {
   set $l4 "1$l3";
}
if ( $l4 = 13) {
   rewrite ^(.*)$ https://www.baidu.com;
}
access_log /tmp/pythotab-access.log xingcheng;
error_log /tmp/pythotab-error.log;
}


釋義:

a.$request_filename 為被請求檔案的路徑,$request_filename ~ ^(.+)/(.+)$為被請求檔案的上級目錄資訊。可以將$l2定義在日誌格式中,透過日誌檢視輸出是否成功。

b.透過 set $l4 "1$l3" ,實際上就代替了邏輯與運算。


四、nginx的rewrite規則參考

- ~ 為區分大小寫匹配

- ~* 為不區分大小寫匹配

- !~和!~*分別為區分大小寫不匹配及不區分大小寫不匹


- -f和!-f用來判斷是否存在檔案

- -d和!-d用來判斷是否存在目錄

- -e和!-e用來判斷是否存在檔案或目錄

- -x和!-x用來判斷檔案是否可執行


- last 相當於Apache裡的[L]標記,表示完成rewrite,呵呵這應該是最常用的

- break 終止匹配, 不再匹配後面的規則

- redirect 返回302臨時重定向 位址列會顯示跳轉後的地址

- permanent 返回301永久重定向 位址列會顯示跳轉後的地址


- $args

- $content_length

- $content_type

- $document_root

- $document_uri

- $host

- $http_user_agent

- $http_cookie

- $limit_rate

- $request_body_file

- $request_method

- $remote_addr

- $remote_port

- $remote_user

- $request_filename

- $request_uri

- $query_string

- $scheme

- $server_protocol

- $server_addr

- $server_name

- $server_port

- $uri


相關文章