Nginx map 使用詳解

map 指令介紹:

map 指令是由 ngx_http_map_module 模塊提供的,默認情況下安裝 nginx 都會安裝該模塊。

map 的主要作用是創建自定義變量,通過使用 nginx 的內置變量,去匹配某些特定規則,如果匹配成功則設置某個值給自定義變量。 而這個自定義變量又可以作於他用。

直接看個例子理解起來比較清晰:

  • 場景: 匹配請求 url 的參數,如果參數是 debug 則設置 $foo = 1 ,默認設置 $foo = 0
map $args $foo {
    default 0;
    debug   1;
}
解釋:

$args 是nginx內置變量,就是獲取的請求 url 的參數。 如果 $args 匹配到 debug 那麼 $foo 的值會被設爲 1 ,如果 $args 一個都匹配不到 $foo 就是default 定義的值,在這裏就是 0

map 語法

map $var1 $var2 {...}
map 指令的三個參數:

1、default : 指定源變量匹配不到任何表達式時將使用的默認值。當沒有設置 default,將會用一個空的字符串作爲默認的結果。

2、hostnames : 允許用前綴或者後綴掩碼指定域名作爲源變量值。這個參數必須寫在值映射列表的最前面。

3、include : 包含一個或多個含有映射值的文件。

  • 在 Nginx 配置文件中的作用段: http{} ,注意 map 不能寫在 server{} 否則會報錯

map 的 $var1 爲源變量,通常可以是 nginx 的內置變量,$var2 是自定義變量。 $var2 的值取決於 $var1 在對應表達式的匹配情況。 如果一個都匹配不到則 $var2 就是 default 對應的值。

  • 一個正則表達式如果以 “~” 開頭,表示這個正則表達式對大小寫敏感。以 “~*”開頭,表示這個正則表達式對大小寫不敏感。
map $http_user_agent $agent {
    default "";
    ~curl curl;
    ~*apachebench" ab;
}    
  • 正則表達式裏可以包含命名捕獲和位置捕獲,這些變量可以跟結果變量一起被其它指令使用。
map $uri $value {
    /abc                       /index.php;
    ~^/teacher/(?<suffix>.*)$  /boy/;
    ~/fz(/.*)                  /index.php?fz=1;                           
}

==注意:不能在map塊裏面引用命名捕獲或位置捕獲變量。如~^/qupeicom/(.*) /peiyin/$1; 這樣會報錯nginx: [emerg] unknown variable==

==注意二:如果源變量值包含特殊字符如‘~’,則要以‘\’來轉義。==

map $http_referer $value {
    Mozilla    111;
    \~Mozilla  222;
}
  • 源變量匹配表達式對應的結果值可以是一個字符串也可以是另外一個變量。
map $http_referer $value {
    Mozilla    'chrom';
    \~safity    $http_user_agent;

實例(一)

  • 使用 map 來實現允許多個域名跨域訪問的問題
如果是允許單域名跨域訪問直接配置就行了,如下:
# 這些配置可以寫在 http{} 或者 server{} 都是支持的。
add_header Access-Control-Allow-Origin "http://www.tutu.com";
add_header Access-Control-Allow-Methods "POST, GET, PUT, OPTIONS, DELETE";
add_header Access-Control-Max-Age "3600";
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept;

#!/bin/bash
# 上面的配置只允許 http://www.tutu.com 跨域訪問,如果要支持所有域名都可以跨域調用該站。  把上面一行改成這樣,不過不推薦這樣做,因爲不安全
add_header Access-Control-Allow-Origin "*";
如果不想允許所有,但是又需要允許多個域名,那麼就需要用到 map
map $http_origin $corsHost {
    default 0;
    "~http://www.haibakeji.com" http://www.haibakeji.com;
    "~http://m.haibakeji.com" http://m.haibakeji.com;
    "~http://wap.haibakeji.com" http://wap.haibakeji.com;
}
server
{
    listen 80;
    server_name www.haibakeji.com;
    root /nginx;
    location /
    {
        add_header Access-Control-Allow-Origin $corsHost;
    }
}

實例(二)

  • 使用源變量(通常是 nginx 內置變量)匹配一些規則,創建自定義變量,然後在頁面輸出. 這通常在調試的時候非常有用

    
    http {
    map $uri $match {
        ~^/hello/(.*) http://www.hello.com/;
    }
    server {
        listen       8080;
        server_name  test.hello.com;
    
        location /hello {
                default_type text/plain;
                echo uri: $uri;
                echo match: $match;
                echo capture: $1;
                echo new: $match$1;
        }


#### map 涉及的性能問題

大家可能會有一個問題,map 既然只能用在 http 段,這是全局的啊。 這個設置會讓訪問所有虛擬主機的請求都要匹配並設置一遍變量的值,然而事實並非如此,對於沒有用到相關變量的請求來說,並不會執行 map 操作。 就沒有性能上的損失。

#### 匹配優先級問題

> 如果匹配到多個特定的變量,如掩碼和正則同時匹配,那麼會按照下面的順序進行選擇:
> 1. 沒有掩碼的字符串
> 2. 最長的帶前綴的字符串,例如: “*.example.com”
> 3. 最長的帶後綴的字符串,例如:“mail.*”
> 4. 按順序第一個先匹配的正則表達式 (在配置文件中體現的順序)
> 5. 默認值

#### map_hash_bucket_size

>- 語法: map_hash_bucket_size size;
>- 默認值: map_hash_bucket_size 32|64|128;
>- 配置段: http
>- 指定一個映射表中的變量在哈希表中的最大值,這個值取決於處理器的緩存。
> 
>- map_hash_max_size
>- 語法: map_hash_max_size size;
>- 默認值: map_hash_max_size 2048;
>- 配置段: http
>- 設置映射表對應的哈希表的最大值。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章