【Nginx知识】nginx路由配置进阶=location+map


在 Nginx 中, map 是一个非常有用的指令,主要用于 根据某个变量的值映射出另一个变量的值。它通常用在 http 上下文中,用来创建自定义变量,这些变量的值是基于其他变量(通常是 $http_*$args$host 等)的值动态决定的。


一、基本语法

map $source_variable $target_variable {
    default     default_value;
    value1      result1;
    value2      result2;
    ...
}

参数说明:

  • map:指令名称。
  • $source_variable:源变量,即你希望根据它的值来进行匹配的变量,比如 $http_user_agent$arg_type$host 等。
  • $target_variable:目标变量,即 map 映射后生成的新变量,可以在后续的配置中引用,如 $proxy_pass$log_format 等。
  • default(可选):当 $source_variable 的值不匹配任何 case 时使用的默认值。
  • value1, value2, …:源变量的可能取值,可以是字符串或正则表达式。
  • result1, result2, …:对应匹配成功后,$target_variable 被设置的值。

二、使用场景示例

示例 1:根据 User-Agent 判断设备类型

http {
    map $http_user_agent $is_mobile {
        default         0;
        "~*Android"     1;
        "~*iPhone"      1;
        "~*iPad"        1;
        "~*Mobile"      1;
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            if ($is_mobile) {
                # 移动端逻辑
                add_header X-Device "Mobile";
            }

            # 其它逻辑
            add_header X-Device "Desktop";
        }
    }
}

🔍 解释:

  • 我们通过检测 $http_user_agent 的内容,判断访问者是否使用移动设备。
  • 如果匹配到 Android、iPhone、iPad 或 Mobile 关键字,则 $is_mobile1,否则为 0
  • 然后在 serverlocation 中可以根据 $is_mobile 做不同的处理。

示例 2:根据请求参数设置变量

http {
    map $arg_type $content_type {
        default       "application/json";
        "xml"         "application/xml";
        "html"        "text/html";
        "json"        "application/json";
    }

    server {
        listen 80;
        server_name api.example.com;

        location /data {
            add_header Content-Type $content_type;
            return 200 "Content type is $content_type";
        }
    }
}

🔍 解释:

  • 用户访问 http://api.example.com/data?type=xml 时,$arg_type 的值是 xml,那么 $content_type 就会被映射为 "application/xml"
  • 如果没有传 type 或者传了未定义的值,默认是 "application/json"

示例 3:基于域名设置不同后端

http {
    map $host $backend {
        hostnames;

        default       backend_default;
        example.com   backend_prod;
        staging.example.com backend_staging;
        dev.example.com backend_dev;
    }

    upstream backend_prod { server 10.0.0.1; }
    upstream backend_staging { server 10.0.0.2; }
    upstream backend_dev { server 10.0.0.3; }
    upstream backend_default { server 10.0.0.99; }

    server {
        listen 80;
        server_name _;

        location / {
            proxy_pass http://$backend;
        }
    }
}

🔍 解释:

  • hostnames; 表示允许使用通配或简化的主机名匹配(如不写 www. 前缀等),但在此例中未用到高级功能。
  • 根据 $host(即客户端请求的域名),选择不同的 upstream 后端服务。
  • 这种方式非常适合多租户、多环境部署。

三、注意事项

  1. map 指令必须放在 http 块中,不能放在 serverlocation 中。
  2. map 是在 Nginx 启动时解析的,运行时不会重新加载映射关系(除非重启或重载配置)。
  3. 匹配优先级:按照书写顺序从上到下匹配,一旦匹配到就不会继续往下匹配,所以把更具体的值放前面
  4. 正则表达式匹配:以 ~ 开头表示区分大小写的正则,~* 表示不区分大小写的正则。
  5. default 是可选的,如果不指定,未匹配到的值会导致 $target_variable 为空。

四、正则匹配示例

http {
    map $http_referer $referer_type {
        default         "direct";
        "~*google\.com" "google";
        "~*baidu\.com"  "baidu";
        "~*yandex\.ru"  "yandex";
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            add_header X-Referer-Type $referer_type;
        }
    }
}

🔍 解释:

  • 根据 $http_referer(来源页面),判断访客是从 Google、百度还是 Yandex 搜索引擎跳转过来的,分别标记为 googlebaiduyandex,否则为 direct

五、总结

功能说明
作用根据一个变量的值,动态生成另一个变量
使用位置仅能在 http 块中使用
常见用途设备检测、A/B测试、多环境路由、日志分类、权限控制等
变量类型源变量和目标变量都是 Nginx 变量(如 $http_xxx, $arg_xxx, $host 等)
匹配方式支持精确匹配、正则匹配,支持 default 默认值

相关文献

【Nginx知识】nginx日志配置详解
【服务器知识】Nginx路由匹配规则说明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

问道飞鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值