在 nginx 中,`map` 指令必须放在 `http` 块内才能生效,它用于将输入变量映射为新的输出变量。配置时只需在 `http { ... }` 内部直接声明 `map $input_variable $output_variable { ... }` 即可,无需额外包含其他模块或设置全局作用域参数,nginx 会自动将其注册到当前 http 上下文中供后续使用。

如何定义基础映射规则
定义基础映射规则时,需要指定源变量和结果变量,并在大括号内逐行编写匹配条件与对应的返回值。默认值通过 `default` 关键字指定,未匹配的行将被忽略并采用默认值。这种结构清晰且易于维护,适合处理简单的字符串或正则表达式映射。

server {
listen 80;
server_name example.com;
# 假设我们有一个自定义头 X-User-Type
map $http_x_user_type $user_level {
default "guest";
"admin" "premium";
"vip" "premium";
"" "anonymous";
}
location / {
# 使用映射后的变量
add_header X-Level $user_level;
return 200 "Hello, $user_level";
}
}
上述配置中,当请求头 `X-User-Type` 为 `admin` 或 `vip` 时,`$user_level` 将被设置为 `premium`;若为空或未提供,则默认为 `guest` 或 `anonymous`(取决于具体逻辑,此处演示了多种情况)。实际运行中,可以通过 curl 测试不同头部值来验证映射结果。
如何使用正则表达式进行复杂匹配
对于更复杂的匹配需求,如路径解析或用户代理识别,可以使用正则表达式作为键。在 `map` 块中,以 `~` 开头的模式表示区分大小写的正则匹配,以 `~*` 开头则表示不区分大小写。这种方式允许从源变量中提取子串并赋值给目标变量,极大增强了灵活性。

server {
listen 80;
server_name example.com;
# 根据 URL 路径中的版本号提取 API 版本
map $uri $api_version {
default "v1";
~^/api/v(\d+)/.* $1;
}
location /api/ {
# 记录使用的 API 版本
access_log /var/log/nginx/api.log combined if=$api_version;
proxy_pass http://backend;
}
}
在这个例子中,如果请求 URI 是 `/api/v2/users`,正则表达式 `~^/api/v(\d+)/.*` 将捕获数字 `2` 并将其赋值给 `$api_version`。这使得后端服务可以根据版本号动态调整行为,而无需修改 Nginx 核心逻辑。注意正则表达式中的捕获组必须用括号包围,以便正确提取所需部分。
如何处理空值或缺失变量的情况
当源变量为空或未定义时,`map` 指令的行为完全依赖于 `default` 参数的设置。如果没有显式指定 `default`,Nginx 会将结果变量设为空字符串。因此,在处理可能缺失的输入(如可选查询参数或可选请求头)时,务必明确定义默认值,以避免意外行为。此外,对于某些特殊字符或保留字,需确保它们在映射表中被正确转义或引用。











