apache的rewrite是支持或者的,用個OR就可以,如果不加OR,多個RewriteCond 羅列累加就是並且的意思。然後nginx的rewrite就沒有這麼好了。那麼如何去實現這樣複雜的功能呢?這就用到了標記功能。
現在出一個簡單的需求: 要求訪問uri以 /abc/開頭的請求,並且user_agent帶有ie6或者firefox關鍵詞的請求需要禁止訪問。
實現方法爲:
set $rule 0;
if ($document_uri ~ '^/abc')
{
set $rule "${rule}1";
}
if ($http_user_agent ~* 'ie6|firefox')
{
set $rule "${rule}2";
}
if ($rule = "012")
{
deny all;
}
這樣就可以實現了。
然後在我實踐過程中,發現一個問題,就是如果定義超過3條rule,當條件中包含兩條和兩條以上的規則同時存在是,需要把兩條規則的條件寫到第4條規則前面。
例如,有一個這樣的需求:實現rewrite的總前提是,所有請求必須以^/abc 目錄爲開頭。其餘規則如下:
1. user_agent 包含 'ipone' 或者'ipad' 或者'ipod' 的請求需要把 *htm 轉發爲 *html;
2. user_agent 不包含 'ipone' 或者'ipad' 或者'ipod' 並且user_agent 包含'ucweb'的請求需要把*htm 轉發爲 *html;
3. user_agent 不包含 'ipone' 或者'ipad' 或者'ipod' 並且user_agent 不包含'ucweb'的請求需要把*html 轉發爲 *htm;
規則語句爲:
set $rule 2;
if ($document_uri ~* '^/abc')
{
set $rule "${rule}1";
}
if ($http_user_agent ~* 'ipad|iphone|ipod')
{
set $rule "${rule}2";
}
if ($rule = "212")
{
rewrite ^(.*)\.htm$ $1\.html redirect;
}
if ($http_user_agent !~* 'ipad|iphone|ipod')
{
set $rule "${rule}3";
}
if ($http_user_agent !~* 'ucweb')
{
set $rule "${rule}4";
}
if ($http_user_agent ~* 'ucweb')
{
set $rule "${rule}5";
}
if ($rule = "2134")
{
rewrite ^(.*)\.html$ $1\.htm redirect;
}
if ($rule = "2135")
{
rewrite ^(.*)\.htm$ $1\.html redirect;
}
注意,上面規則把 $rule = "212" 放到了上面,如果放到下面則不能實現跳轉。
nginx rewrite (不支持if 嵌套也不支持邏輯或和邏輯並)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.