Nginx 的 map 指令通过统一抽象 $device 变量实现 UA 驱动的自动适配,贯穿缓存、路由、静态路径与用户偏好控制全流程;优先读取 Cookie 中的 device 值, fallback 到 UA 识别,避免 if 嵌套,提升性能与可维护性。

用 Nginx 的 map 指令实现 UA 驱动的移动端/桌面端自动适配,关键在于把设备类型提前抽象成变量(如 $device),再让这个变量贯穿缓存、路由、静态路径和用户偏好控制全流程。它不是在每个 location 里写 if 判断,而是统一识别、集中分发,既高效又易维护。
一、用 map 统一识别设备类型
在 http 块中定义标准化的 $device 变量,覆盖主流移动 UA 特征:
- 正则匹配不区分大小写,用
~*;包含 Android、iPhone、iPad、iPod、BlackBerry、WebOS、Opera Mini、Mobile Safari 等典型标识 - 未匹配项默认设为
"pc",避免空值引发后续逻辑异常 - 避免嵌套否定写法(如
!~* PC),防止正则回溯拖慢请求处理
示例配置:
map $http_user_agent $device {default "pc";
~* "(Android|iPhone|iPad|iPod|BlackBerry|WebOS|Opera Mini|Mobile Safari)" "mobile";
}
二、让缓存系统“感知”设备差异
同一 URL 返回不同内容时,若缓存键不区分设备,就会出现 PC 用户看到移动页、或反之的错乱。解决方式是将 $device 显式加入缓存键:
- 对于 FastCGI:在
fastcgi_cache_key中加入$device,例如:fastcgi_cache_key "$scheme$request_method$host$request_uri$device"; - 对于反向代理:同理设置
proxy_cache_key - 若使用 CDN(如腾讯云 EdgeOne),需额外加响应头:
add_header Vary "User-Agent";,确保边缘节点按 UA 分层缓存
三、动态分发内容与资源路径
$device 不仅用于缓存,还可驱动实际内容输出:
- 后端路由分离:配合
upstream,让mobile请求走backend-mobile,pc走backend-pc - 静态资源路径切换:用
root /usr/share/nginx/html/$device;,前提是提前建好/html/pc和/html/mobile目录,否则返回 404 - 也可结合
try_files实现 fallback,例如:try_files /$device$uri /pc$uri =404;
四、支持用户手动切换并优先生效
自动识别可能不准,需提供“切换到手机版/电脑版”入口,并通过 Cookie 尊重用户选择:
- 前端点击时设置 Cookie,如
device=mobile或device=pc - 在 map 定义中优先读取
$cookie_device,再回落到 UA 识别:map $cookie_device $device {<br> default "";<br> ~* mobile "mobile";<br> ~* pc "pc";<br>}<br>map $http_user_agent $ua_device { ... }<br>map $cookie_device $device {<br> default $ua_device;<br> ~* mobile "mobile";<br> ~* pc "pc";<br>}

















