map 比 if + rewrite 更高效,因其在启动时构建 O(1) 哈希表,避免每次请求的正则匹配开销;正确用法是 http 块定义 map 预计算目标路径,server 中用 if 判断后 return 301 跳转。

直接用 map 替代一堆 if + rewrite,是处理海量静态重定向最轻量、最高效的方式。它把路径映射逻辑从每次请求时的运行时匹配,提前到配置加载阶段完成,彻底避开正则引擎和条件判断开销。
为什么 map 比 if + rewrite 快得多
map 是 Nginx 的静态哈希映射机制,在 nginx 启动时就编译好查找表,查询时间复杂度为 O(1);而 if 块内套 rewrite 每次都要触发 PCRE 正则匹配,哪怕写成 rewrite ^/old /new permanent,也会加载正则引擎、执行模式编译与匹配——这对高频访问的跳转规则来说,是明显的性能瓶颈。
- map 不依赖正则,只做精确字符串匹配(如
/a→/b) - map 定义在
http块,全局生效,复用率高 - map 变量可被任意 server 或 location 引用,逻辑解耦清晰
正确写法:map 定义 + return 调用
不要在 map 里写重定向动作,也不要在 location 里用 rewrite 调 map 变量。标准组合是:map 预计算目标路径,server 中用 if 判断是否需要跳转,再用 return 301 直接响应。
- 在
http{}块顶部定义映射:
map $uri $redirect_to {
/old /new;
/about /about-us;
/blog /articles;
/contact /help;
default "";
}
- 在
server{}中调用(放在 listen 和 server_name 下方,越靠前越好):
if ($redirect_to) {
return 301 $redirect_to;
}
- 注意:
default ""表示不匹配时不跳转,避免误重定向 - 不要用
rewrite或permanent标志,return 是零开销指令
进阶技巧:支持带参数或 host 判断的跳转
map 本身不支持正则或动态拼接,但可以配合其他变量实现更灵活逻辑。例如统一跳转到 HTTPS+www:
- 先用 map 判断 host 是否需要加 www:
map $host $www_host {
~^example\.com$ www.example.com;
default $host;
}
- 再在 server 中组合使用:
if ($scheme = http) {
return 301 https://$www_host$request_uri;
}
- $request_uri 自动保留原始路径和 query string,无需手动拼接
- 多个 map 可叠加使用(如一个管路径,一个管 host),互不干扰
避坑提醒:哪些事千万别做
- 别在 map 中写正则表达式(如
~^/old.*$)——会退化为运行时匹配,失去性能优势 - 别把 map 放在 server 块里——必须定义在 http 块,否则无法全局共享
- 别用
rewrite ... permanent处理 map 结果——return 才是配套指令 - 别让 map 规则频繁变更——每次 reload 都要重建哈希表,小范围更新建议用灰度 server 分流



















