Nginx 中 map 指令不能直接返回状态码,但可将路径映射为变量(如 $dynamic_code),再通过 return 或 error_page 实现动态响应;map 必须定义在 http 块,仅支持字面量映射,需配合 return $dynamic_code 或 error_page 使用。

在 Nginx 中,map 指令本身不能直接返回 HTTP 状态码,但它可以配合 return 或 error_page 实现基于请求路径的动态状态码控制——关键在于把路径映射为变量值,再用该变量触发响应行为。
用 map 提取路径特征并映射状态码变量
map 必须定义在 http 块中,它根据匹配规则将输入(如 $request_uri 或 $uri)映射为一个自定义变量。注意:只支持字符串或数字字面量,不支持执行指令。
例如,针对特定路径前缀返回不同状态码:
http {
map $uri $dynamic_code {
~^/maintenance/ 503;
~^/deprecated/api 410;
~^/v1/ 301;
default 200;
}
}
这里用正则匹配 $uri(不含 query string 的规范化路径),将结果赋给 $dynamic_code 变量。
在 server 或 location 中使用映射变量控制响应
仅定义 map 不会自动生效,需在具体作用域中调用变量。最直接的方式是用 return 指令:
- 在
server或location块中写return $dynamic_code;,Nginx 会立即返回对应状态码(不走后续处理) - 若需带响应体,可加第二参数:
return $dynamic_code "Under maintenance"; - 注意:如果
$dynamic_code为 0 或空字符串,Nginx 会报错,所以default分支建议设为有效状态码(如 200 或 404)
结合 error_page 实现更灵活的跳转或定制响应
当需要返回带页面的状态码(如 503 页面),或统一处理多个映射码时,可用 error_page 中转:
location / {
return $dynamic_code;
error_page 503 /503.html;
error_page 410 /410.html;
internal;
}
或更通用的方式(避免重复写 error_page):
map $dynamic_code $error_page_path {
503 "/503.html";
410 "/410.html";
301 "/redirect-v1.html";
default "";
}
<p>server {
location / {
if ($error_page_path != "") {
return $dynamic_code;
}</p><h1>正常代理或静态服务</h1><pre class="brush:php;toolbar:false;"> proxy_pass http://backend;
}
location ~ ^/(503|410|redirect-v1)\.html$ {
internal;
root /usr/share/nginx/html;
}}
注意事项与常见陷阱
-
map是惰性求值的:变量只在首次被引用时计算,且不支持嵌套或条件链式判断 - 正则匹配优先级从上到下,建议把更具体的模式(如
/v1/users)放在通用模式(如/v1/)之前 -
$request_uri包含 query string,$uri经过解码且不带参数,多数场景推荐用$uri - 状态码变量不能用于
proxy_pass或rewrite,仅适用于return、error_page、add_header等少数指令











