Nginx可通过map指令将请求头(如X-ENV-ID)映射为变量,结合root或proxy_pass实现基于Header的动态静态资源分发与后端路由,支持灰度发布、多环境共存及主干兜底,需注意路径权限、underscores_in_headers开启及缓存键包含Header。

直接用 map 指令把请求头映射成变量,再结合 root 或 proxy_pass 动态路由,就能实现基于 Header 的静态资源分发。核心不是写一堆 if 判断,而是靠 map 做声明式映射,既安全又高效。
用 map 映射 Header 到资源目录
这是最常用也最推荐的方式,适合灰度发布、多环境共存等场景:
- 在
http块里定义map,把自定义 Header(如X-ENV-ID)值映射为本地文件路径 - 支持
default回退,避免未匹配时出错 - 路径必须是绝对路径,且 Nginx 进程要有读取权限
示例配置:
http {
map $http_x_env_id $static_root {
default /usr/share/nginx/html/prod;
"staging" /usr/share/nginx/html/staging;
"dev" /usr/share/nginx/html/dev;
}
<pre class="brush:php;toolbar:false;">server {
listen 80;
location / {
root $static_root;
try_files $uri $uri/ =404;
}
}}
用 map + proxy_pass 分发到不同后端
当静态资源托管在不同服务器(比如对象存储、CDN源站或多个 Nginx 节点)时,更适合用 proxy_pass:
- 把 Header 值映射为 upstream 名或完整 URL
- 配合
upstream实现健康检查和负载均衡 - 记得加
underscores_in_headers on;,否则带下划线的 Header(如X_ENV_ID)会被忽略
示例:
http {
underscores_in_headers on;
<pre class="brush:php;toolbar:false;">map $http_x_env_id $backend {
default static-prod.example.com;
"beta" static-beta.example.com;
"canary" static-canary.example.com;
}
server {
listen 80;
location ~* \.(js|css|png|jpg|gif)$ {
proxy_pass https://$backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}}
配合 fallback 实现“主干兜底”
分支环境往往只覆盖部分资源(比如只改了 JS,没动图片),这时可让缺失资源自动回退到主干目录:
- 用
try_files尝试当前环境路径,失败后跳转到命名 location - 命名 location 中指定主干路径,并再次尝试查找
- 避免因分支缺文件导致 404,提升灰度体验
示例:
location / {
root $static_root;
try_files $uri $uri/ @fallback;
}
location @fallback {
root /usr/share/nginx/html/prod;
try_files $uri $uri/ =404;
}注意缓存与 Header 协同
Header 分发改变了资源来源,但默认缓存策略可能失效:
- 浏览器缓存:对带哈希指纹的文件(
app.a1b2c3.js)仍可设 long cache;无版本号文件建议用ETag或Last-Modified校验 - CDN 缓存:需在 CDN 配置中将该 Header 加入缓存键(Cache Key),否则不同 Header 请求会命中同一缓存
- Nginx 本地缓存:若用
proxy_cache,也要把$http_x_env_id加入cache_key,避免混用


















