Nginx通过正则匹配$http_user_agent提取Chrome/Firefox/Safari版本号并存入变量,再用数值或字符串比较实现低版本浏览器降级跳转。

在 Nginx 中,Rewrite 规则本身不直接“检测浏览器版本”,而是通过正则匹配 $http_user_agent 字符串中的版本标识(如 Chrome/125、Firefox/118、Safari/605.1.33 等)来实现粗粒度的版本识别,并据此触发重定向或路径改写。这种方式轻量、无需额外模块,但依赖 UA 字符串的可读性与稳定性。
提取并匹配常见浏览器版本号
多数主流浏览器会在 User-Agent 中明确携带版本字段,可用 ~*(不区分大小写)配合正则捕获组提取:
-
if ($http_user_agent ~* "Chrome/([0-9]{2,})") { set $chrome_ver $1; }—— 提取 Chrome 主版本号到变量$chrome_ver -
if ($http_user_agent ~* "Firefox/([0-9]{2,})") { set $ff_ver $1; }—— 同理提取 Firefox 版本 -
if ($http_user_agent ~* "Safari/([0-9]+\.?[0-9]*)") { set $safari_ver $1; }—— Safari 版本常含小数,需适配
注意:set 必须在 if 内使用,且变量作用域限于当前请求;多个 if 是独立判断,不会短路。
对低版本浏览器执行降级跳转
拿到版本号后,可用数值比较(Nginx 1.19+ 支持原生整数比较)或字符串前缀匹配实现降级逻辑:
- Chrome 旧版(≤110)跳转至兼容页面:
if ($chrome_ver ~* "^([0-9]|1[0-9]|10[0-9])$") { rewrite ^/(.*)$ /legacy/$1?from=old-chrome redirect; } - Firefox ≤102 强制走静态资源路径:
if ($ff_ver - Safari 版本低于 605.1(对应 macOS Monterey 早期)时跳转提示页:
if ($safari_ver ~* "^([0-9]|[1-5][0-9]|60[0-4]|605\.[0-0])") { return 302 https://example.com/outdated-safari.html; }
规避 UA 伪造与匹配陷阱
User-Agent 可被轻易修改,该方案仅适用于体验优化类降级,不可用于权限或安全控制:
- 避免用
if嵌套或复杂逻辑——Nginx 的if是伪指令,性能差且易出错;优先用return或单层rewrite - 匹配 Safari 要加
AppleWebKit限定,防止误命中 Chrome(因 Chrome UA 也含 Safari 字样):if ($http_user_agent ~* "Safari/.*AppleWebKit") { ... } - Edge 新版 UA 含
Edg/,旧版含Edge/,建议双模式覆盖:if ($http_user_agent ~* "(Edg|Edge)/([0-9]{2,})") { set $edge_ver $2; }
替代更可靠方案的提示
若需精确识别(如 WebAssembly 支持、CSS 新特性),仅靠 UA 不足:
- 前端 JS 检测特性后通过 API 上报或设置 Cookie,Nginx 读取
$cookie_browser_cap再决策 - 结合
map指令预定义 UA 分类,比反复if更高效:map $http_user_agent $browser_type { ~*Chrome chrome; ~*Firefox firefox; ~*Safari.*AppleWebKit safari; default other; } - 真正关键的降级逻辑(如登录页兼容)建议由后端统一处理,Nginx 仅做轻量路由分发


















