Nginx 不支持原生 if-else,但可通过 if + $http_user_agent 实现浏览器识别分流,推荐用 map 预定义映射更高效安全;rewrite 需配合 break/last,且所有条件判断必须在 location 块内。

Nginx 本身不支持在 rewrite 指令中直接写复杂的 if-else 分支逻辑,但可以通过 if 指令结合 $http_user_agent 变量做浏览器识别,并配合 set、rewrite 或 return 实现分流。关键在于:条件判断必须放在 location 块内,且需注意 if 的使用限制(比如不能嵌套、部分指令在 if 中无效)。
识别常见浏览器并设置分流标记
利用 $http_user_agent 匹配特征字符串,用 set 定义变量标识浏览器类型,便于后续统一处理:
location / {
set $browser "";
if ($http_user_agent ~* "MSIE|Trident|Edge") {
set $browser "ie";
}
if ($http_user_agent ~* "Firefox") {
set $browser "firefox";
}
if ($http_user_agent ~* "Chrome.*Safari") {
set $browser "chrome";
}
if ($http_user_agent ~* "Safari.*!Chrome") {
set $browser "safari";
}
# 后续可基于 $browser 变量做 rewrite 或 proxy_pass
}用 rewrite 实现 URL 重写式分流
当需要将不同浏览器请求导向不同路径(如静态资源版本、前端构建产物目录),可用 rewrite 配合 break 或 last:
location /app/ {
set $target "/app/";
if ($browser = "ie") {
rewrite ^/app/(.*)$ /app/ie/$1 break;
}
if ($browser = "chrome") {
rewrite ^/app/(.*)$ /app/chrome/$1 break;
}
if ($browser = "safari") {
rewrite ^/app/(.*)$ /app/safari/$1 break;
}
# 默认走原路径
try_files $uri $uri/ =404;
}注意:rewrite ... break 表示内部重写后停止匹配当前 location 内其他 rewrite;若需重新匹配 location,则用 last(慎用,避免循环)。
在 Linux 上通过 Chrome 挂载/VNC 自动发布小红书长笔记。Agent 撰写标题和正文后执行 xhs_publish.sh --publish --submit,触发小红书发布。
更可靠的方式:用 map 预定义浏览器映射
map 指令比多个 if 更高效、更安全,推荐在 http 块中提前定义:
http {
map $http_user_agent $browser_type {
default "other";
"~*MSIE|Trident|Edge" "ie";
"~*Firefox" "firefox";
"~*Chrome.*Safari" "chrome";
"~*Safari.*!Chrome" "safari";
"~*Edg" "edge";
}
<pre class="brush:php;toolbar:false;">server {
location / {
# 根据 $browser_type 重写
if ($browser_type = "ie") {
rewrite ^(.*)$ /ie$1 break;
}
if ($browser_type = "chrome") {
rewrite ^(.*)$ /chrome$1 break;
}
# 其他逻辑...
}
}}
map 是惰性求值、线程安全的,不会像 if 那样引发重复执行或意外覆盖问题,适合生产环境。
注意事项与避坑点
-
if在 location 外不可用 rewrite / set 等指令,必须包裹在 location 或 server 块中 - 多个
if是顺序执行、非互斥的,需注意正则匹配重叠(例如 Chrome UA 也含 Safari,应把 Chrome 条件放 Safari 前面) - 避免在 if 中使用 proxy_pass、root 等指令——它们可能不生效;优先用 rewrite + try_files 或 map + proxy_pass
- 移动端浏览器(如 iOS Safari、Android Chrome)UA 字符串较复杂,建议用
~*不区分大小写匹配,并测试真实 UA - 上线前务必用 curl -A 模拟不同 UA 验证效果:
curl -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" http://localhost/app/test.js










