Nginx可通过map指令结合User-Agent、Cookie、Header或URL路径实现客户端版本路由,动态映射静态资源目录,支持灰度发布、A/B测试与原子部署,并需配合Vary头和哈希缓存策略避免版本错乱。

Nginx 本身不内置用户识别或客户端版本路由能力,但可以通过 请求头(如 User-Agent、自定义 Header)、Cookie 或 URL 路径 等字段做条件判断,结合 map 指令 + root/alias 动态切换静态资源目录,实现“不同客户端看到不同版本”的效果。核心是把客户端特征映射为路径变量,再让 location 或 root 引用它。
✅ 基于 User-Agent 区分移动端与桌面端
适合响应式降级、老浏览器兼容包等场景。例如:
- 移动端访问
/static/→ 实际读取/var/www/static/mobile/ - 桌面端访问
/static/→ 实际读取/var/www/static/desktop/
http {
# 定义映射:根据 $http_user_agent 决定资源根目录
map $http_user_agent $static_root {
default "/var/www/static/desktop";
"~*Mobile" "/var/www/static/mobile";
"~*Android" "/var/www/static/mobile";
"~*iPhone" "/var/www/static/mobile";
}
server {
listen 80;
location /static/ {
alias $static_root/;
expires 1h;
add_header Cache-Control "public, immutable";
}
}
}⚠️ 注意:
alias后必须带末尾/,且$static_root值末尾也需带/;root不适用此处,因为它会拼接完整 URI 路径。
✅ 基于 Cookie 或 Header 指定灰度版本
适用于 A/B 测试、内部预发通道、VIP 用户资源定制等。例如:
- 请求带
X-Client-Version: v2→ 读取/var/www/static/v2/ - 请求带
Cookie: version=beta→ 读取/var/www/static/beta/
http {
map $http_x_client_version $version_path {
default "v1";
"v2" "v2";
"beta" "beta";
}
map $cookie_version $cookie_path {
"beta" "beta";
default $version_path;
}
server {
location / {
root /var/www/static/$cookie_path;
index index.html;
try_files $uri $uri/ =404;
}
}
}✅ 支持组合逻辑:优先取 Header,未设置时 fallback 到 Cookie。
map支持嵌套和 fallback,但不能写复杂表达式。
✅ 基于 URL 路径显式指定版本(最简单可靠)
把版本号暴露在路径中,如 /v2/, /beta/,由前端或发布流程控制入口。Nginx 配置清晰、无状态、易调试:
server {
location ^~ /v1/ {
alias /var/www/static/v1/;
expires 1y;
add_header Cache-Control "public, immutable";
}
location ^~ /v2/ {
alias /var/www/static/v2/;
expires 1y;
add_header Cache-Control "public, immutable";
}
location / {
# 默认指向 current 软链接(用于原子发布)
alias /var/www/static/current/;
index index.html;
try_files $uri $uri/ =404;
}
}✅ 推荐搭配原子发布策略:
/v1/和/v2/是固定版本,/指向current,可随时切换,兼顾稳定性与灵活性。
✅ 补充:配合缓存避免版本错乱
不同版本资源必须有独立缓存标识,否则浏览器可能复用旧版 JS 导致报错:
- 所有静态资源加哈希后缀(如
app.a1b2c3.js),启用长缓存(expires 1y) - HTML 文件禁用强缓存(
Cache-Control: no-cache或max-age=0),确保能及时加载新入口 - 若用 Cookie/UA 切换,建议对 HTML 加
Vary: User-Agent, Cookie头,让 CDN/代理正确区分缓存:
location ~ \.html$ {
add_header Vary "User-Agent, Cookie";
expires -1;
add_header Cache-Control "no-cache, must-revalidate";
}不复杂但容易忽略


















