在 nginx 中实现根据浏览器类型分发不同页面,核心做法是利用 `map` 指令将 http 请求头中的 user-agent 解析为自定义变量(如 $browser_type),然后在 location 块中使用 if 或 try_files 配合该变量进行条件判断。具体而言,需在 http 上下文定义映射规则,并在 server 或 location 中通过 root 或 alias 指向不同的静态目录,这样当客户端访问时,nginx 会根据 ua 匹配到的类型加载对应的 html 文件。

如何配置 map 指令以识别特定浏览器
要准确识别浏览器,需要在 http 块中定义一个 map 块,将 $http_user_agent 映射到自定义变量。例如,可以设置当 User-Agent 包含 "Chrome" 时,变量值为 "chrome",否则为 "other"。这种配置允许后续逻辑基于简化的标签进行分支处理,避免在 location 中编写复杂的正则表达式。

http {
# 定义映射:将 User-Agent 映射到 browser_type
map $http_user_agent $browser_type {
default 'other';
~*Chrome 'chrome';
~*Safari 'safari';
~*Firefox 'firefox';
}
server {
listen 80;
server_name example.com;
# 主 location 块
location / {
# 根据变量值决定根目录
if ($browser_type = 'chrome') {
root /var/www/html/chrome;
}
if ($browser_type = 'safari') {
root /var/www/html/safari;
}
# 默认根目录
root /var/www/html/default;
index index.html;
}
}
}
如何处理多条件分支与默认回退
当需要支持更多浏览器或更复杂的逻辑时,可以在 map 中添加更多正则匹配项。Nginx 的 map 指令按顺序匹配,第一个匹配成功的规则生效。若没有匹配项,则使用 default 指定的值。在 location 中,可以使用多个 if 语句来切换 root 路径,或者使用 try_files 尝试不同目录下的文件。需要注意的是,if 在 location 中的行为有时令人困惑,因此推荐仅用于设置变量或重定向,对于简单的目录切换,上述 root 赋值方法是有效的。

# 扩展的 map 配置示例
map $http_user_agent $browser_type {
default 'other';
~*Chrome 'chrome';
~*Safari 'safari';
~*Firefox 'firefox';
~*Edge 'edge';
}
# 在 location 中使用 try_files 进行多目录尝试
location / {
set $base_root /var/www/html/default;
if ($browser_type = 'chrome') {
set $base_root /var/www/html/chrome;
}
if ($browser_type = 'safari') {
set $base_root /var/www/html/safari;
}
# 尝试从指定目录加载 index.html
try_files $uri $uri/ $base_root/index.html =404;
}
当 User-Agent 为空或包含特殊字符时会发生什么
如果客户端发送的请求中 User-Agent 头为空,或者其内容不匹配 map 中定义的任何正则表达式,Nginx 会将 $browser_type 设置为 default 指定的值(在上述示例中为 'other')。这意味着请求将落入默认的处理逻辑,即访问 /var/www/html/default 目录。此外,如果 User-Agent 中包含特殊字符(如空格、引号等),Nginx 会自动对其进行转义或忽略,不会影响 map 的正则匹配过程,但建议在实际部署前测试各种 UA 字符串以确保兼容性。











