最直接方式是通过正则匹配navigator.userAgent字符串:/Android/i→android,/iPhone|iPad|iPod/i→ios,/Mac OS X|macOS/i→macos,/Windows/i→windows,/Linux/i→linux;需特别处理iOS 13+ iPad UA伪装问题。

用 navigator.userAgent 判断系统类型最直接
浏览器本身不提供“系统类型”这个现成字段,但 navigator.userAgent 字符串里包含操作系统标识,是实际项目中最常用、兼容性最好的方式。它在所有现代浏览器(包括 Chrome、Firefox、Safari、Edge)以及绝大多数移动端 WebView 中都可用。
注意:这不是 100% 可靠(用户可伪造 UA),但对表单提交时做前端轻量级适配(比如默认勾选“Mac 用户偏好深色模式”、或隐藏 Windows 不支持的快捷键提示)完全够用。
常见匹配逻辑如下:
-
/Windows/i→ 匹配 Windows(含 Windows 10/11、Windows Phone) -
/Mac OS X|macOS/i→ 匹配 macOS(注意 Safari 17+ UA 中已从Mac OS X改为macOS) -
/Linux/i→ 匹配 Linux 桌面(不含 Android) -
/Android/i→ 匹配 Android 系统(优先级高于 Linux,避免误判) -
/iPhone|iPad|iPod/i→ 匹配 iOS 设备(注意 iPad 在 iOS 13+ 后 UA 可能带Macintosh,需结合platform或二次检测)
表单提交前把系统类型写进隐藏字段
别试图在后端解析 UA —— 那会丢失原始上下文,且服务端 UA 可能被代理重写。正确做法是在表单提交前,用 JS 把识别结果塞进一个 字段,和服务端数据一并提交。
示例代码:
<script> function getOSType() { const ua = navigator.userAgent; if (/Android/i.test(ua)) return 'android'; if (/iPhone|iPad|iPod/i.test(ua)) return 'ios'; if (/Mac OS X|macOS/i.test(ua)) return 'macos'; if (/Windows/i.test(ua)) return 'windows'; if (/Linux/i.test(ua)) return 'linux'; return 'unknown'; } document.getElementById('myForm').addEventListener('submit', function() { document.getElementById('osTypeField').value = getOSType(); }); </script>这样后端收到的 POST 数据里就会有 os_type=macos 这样的字段,无需额外解析 UA。
别依赖 navigator.platform 或 navigator.oscpu
这两个字段看似更“干净”,但实际坑很多:
-
navigator.platform在 Chrome 和 Firefox 中对 macOS 返回MacIntel,在 Safari 17+ 返回MacIntel或MacPPC,但 iPadOS 16+ 也可能返回MacIntel(即使设备是 iPad),完全不可靠; -
navigator.oscpu在 Chrome 中已被移除,在 Safari 中始终为空,Firefox 仅部分版本支持,且格式不统一(如Windows NT 10.0vsLinux x86_64); - 它们都不包含 iOS/Android 的明确标识,无法区分移动和桌面生态。
所以除非你只支持非常老的内网环境,否则不要碰这两个字段。
iOS 13+ iPad 的 UA 混淆问题必须单独处理
iOS 13 起,iPad 默认 UA 会伪装成 macOS + MacIntel,例如:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15
这会导致 /Mac OS X/i 匹配成功,但设备其实是 iPad。解决办法是加一层设备能力判断:
- 检查
navigator.maxTouchPoints > 0(iPad 支持触控,Mac 不支持); - 或检查
matchMedia('(pointer: coarse)').matches(粗粒度指针通常表示触屏设备); - 更稳妥的是组合判断:
/Mac OS X|macOS/i.test(ua) && 'ontouchend' in window(iPad 有 touch 事件,Mac 没有)。
单纯靠字符串匹配 iOS 已经不够用了,这点容易被忽略,上线后才发现 iPad 用户被当成 Mac 处理。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











