可行,通过map指令将$http_user_agent映射为$device_root变量,在location中用root /usr/share/nginx/html/$device_root动态指定路径,实现iPhone/Android等设备的静态资源分流。

直接通过 Nginx 原生配置按设备类型(iPhone/Android)下发不同静态资源包,不可行。Nginx 本身不解析 User-Agent 后动态切换 root 或 alias 路径——它没有运行时变量拼接能力,也不支持基于请求头重写文件系统路径。但可以通过合理组合 map、root 变量和目录结构实现效果等价的分流。
核心思路:用 map 提前映射设备类型到路径前缀
Nginx 允许在 http 块中用 map 指令根据 $http_user_agent 提取设备标识,并映射为一个变量(如 $device_root),再在 location 中引用该变量作为 root 的一部分。
- 需确保静态资源按设备组织好目录结构,例如:
/usr/share/nginx/html/iphone//usr/share/nginx/html/android//usr/share/nginx/html/common/ - 在
http{}块顶部添加:
default "common";
~*[iI]phone|iPhone|iPad "iphone";
~*[aA]ndroid|Android "android";
}
配置 location 使用动态 root
在 server{} 块中,不再用固定 root,而是让每个静态资源路径根据设备自动选择子目录:
- 例如,所有
/static/请求都走设备专属路径: - location /static/ {
root /usr/share/nginx/html/$device_root;
expires 1h;
add_header Cache-Control "public";
} - 注意:
root后接变量是合法的,Nginx 会在每次请求时求值;而alias不支持变量,所以必须用root+ 路径拼接方式 - 请求
/static/app.js在 iPhone 上实际读取:/usr/share/nginx/html/iphone/static/app.js
关键细节与限制
- User-Agent 可被伪造或缺失,
map默认值(如common)必须存在且可用 - 确保 Nginx 有权限读取所有子目录,比如执行:
sudo chmod -R 755 /usr/share/nginx/html/{iphone,android,common} - 不建议对
/根路径做设备分流,易导致 HTML 渲染错乱;专注静态资源(/static/、/js/、/css/、/images/)更安全 - 若需区分 iOS 版本或 Android 品牌,正则可细化,但过度判断会增加维护成本
验证与上线步骤
- 修改后先测试语法:
sudo nginx -t - 成功后重载:
sudo nginx -s reload - 用 curl 模拟不同 UA 验证:
curl -H "User-Agent: Mozilla/5.0 (iPhone..." http://localhost/static/app.jscurl -H "User-Agent: Mozilla/5.0 (Linux; Android..." http://localhost/static/app.js - 检查响应内容是否来自对应子目录,以及 HTTP 头中
Content-Length是否匹配预期文件











