如何通过index.html识别访客是使用手机还是电脑访问?
- 内容介绍
- 文章标签
- 相关推荐
本文共计929个文字,预计阅读时间需要4分钟。
直接读取 `navigator.userAgent` 字符串,检查是否包含常见移动端关键词。这是兼容性最好、零依赖的方案,适用于所有现代浏览器(包括微信内置浏览器)。
注意:不能只看 "Mobile",因为部分 iPad UA 不含该字段;也不能只看 "iPad",因为 iOS 13+ 的桌面模式会主动隐藏它。
-
/Mobi|Android|iPhone|iPod|Opera Mini|IEMobile/i.test(navigator.userAgent)—— 覆盖绝大多数手机 - 若需区分 iPad,加
|| /iPad/i.test(navigator.userAgent) && !/Macintosh.*Safari/i.test(navigator.userAgent)(避免误判 macOS Safari) - 别用
indexOf("Android") !== -1这类写法,大小写不安全,正则更稳
用 matchMedia 判断视口宽度更可靠
UA 可被伪造或修改,而 window.matchMedia 基于真实设备能力,适合做响应式降级逻辑(比如在 PC 端强制加载桌面版地图组件)。
关键点:它不等于“屏幕物理尺寸”,而是当前 viewport 的有效宽度(受缩放、横竖屏影响)。
立即学习“前端免费学习笔记(深入)”;
-
matchMedia("(max-width: 768px)").matches是常用阈值,但不是绝对标准——有些折叠屏展开后也满足该条件 - 推荐组合判断:
matchMedia("(max-width: 768px)").matches && navigator.maxTouchPoints > 1,兼顾尺寸与触控能力 - 监听变化时用
mediaQuery.addListener(handler),注意旧版 Safari 需用addRule兼容
服务端 UA 检测比前端更早,但有局限
如果 index.html 是由后端渲染(如 PHP/Nginx),可在 HTTP 请求头中解析 User-Agent,直接输出不同 HTML 或 class。这样首屏无需 JS 就能适配。
问题在于:CDN 缓存、爬虫 UA、微信/QQ 内置浏览器 UA 标识混乱,容易误判。
- Nginx 示例:
if ($http_user_agent ~* "(Mobi|Android|iPhone)") { set $is_mobile "1"; },再通过try_files分流 - PHP 中建议用现成库(如
sinergi/browser-detector),自己正则匹配易漏 Edge Mobile、Samsung Browser 等变体 - 纯静态托管(GitHub Pages / Vercel)无法做服务端判断,只能靠前端
别忽略微信和 QQ 内置浏览器的特殊行为
它们 UA 字符串里同时含 "MicroMessenger" 和 "Mobile",但部分安卓微信版本会把 UA 改成桌面格式(伪装成 Chrome),导致前端 UA 判断失效。
此时 matchMedia + 'ontouchstart' in window 组合更准,但要注意:Chrome 桌面版开启开发者工具模拟移动设备时,ontouchstart 也会存在。
- 简单兜底:
!!navigator.userAgent.match(/MicroMessenger/i) || !!navigator.userAgent.match(/QQ\/\d+/i) - 真机检测建议加一层:检查
screen.width < 900 && 'ontouchstart' in window,排除桌面模拟场景 - 微信 JS-SDK 的
getNetworkType不能用于设备判断,它返回的是网络类型
实际项目里,多数情况用 navigator.userAgent + matchMedia 双保险就够了。真正难处理的是那些 UA 被刻意抹除或篡改的环境,比如某些企业微信定制版、鸿蒙 WebView 的早期版本——这时候得靠用户手动切换按钮兜底。
本文共计929个文字,预计阅读时间需要4分钟。
直接读取 `navigator.userAgent` 字符串,检查是否包含常见移动端关键词。这是兼容性最好、零依赖的方案,适用于所有现代浏览器(包括微信内置浏览器)。
注意:不能只看 "Mobile",因为部分 iPad UA 不含该字段;也不能只看 "iPad",因为 iOS 13+ 的桌面模式会主动隐藏它。
-
/Mobi|Android|iPhone|iPod|Opera Mini|IEMobile/i.test(navigator.userAgent)—— 覆盖绝大多数手机 - 若需区分 iPad,加
|| /iPad/i.test(navigator.userAgent) && !/Macintosh.*Safari/i.test(navigator.userAgent)(避免误判 macOS Safari) - 别用
indexOf("Android") !== -1这类写法,大小写不安全,正则更稳
用 matchMedia 判断视口宽度更可靠
UA 可被伪造或修改,而 window.matchMedia 基于真实设备能力,适合做响应式降级逻辑(比如在 PC 端强制加载桌面版地图组件)。
关键点:它不等于“屏幕物理尺寸”,而是当前 viewport 的有效宽度(受缩放、横竖屏影响)。
立即学习“前端免费学习笔记(深入)”;
-
matchMedia("(max-width: 768px)").matches是常用阈值,但不是绝对标准——有些折叠屏展开后也满足该条件 - 推荐组合判断:
matchMedia("(max-width: 768px)").matches && navigator.maxTouchPoints > 1,兼顾尺寸与触控能力 - 监听变化时用
mediaQuery.addListener(handler),注意旧版 Safari 需用addRule兼容
服务端 UA 检测比前端更早,但有局限
如果 index.html 是由后端渲染(如 PHP/Nginx),可在 HTTP 请求头中解析 User-Agent,直接输出不同 HTML 或 class。这样首屏无需 JS 就能适配。
问题在于:CDN 缓存、爬虫 UA、微信/QQ 内置浏览器 UA 标识混乱,容易误判。
- Nginx 示例:
if ($http_user_agent ~* "(Mobi|Android|iPhone)") { set $is_mobile "1"; },再通过try_files分流 - PHP 中建议用现成库(如
sinergi/browser-detector),自己正则匹配易漏 Edge Mobile、Samsung Browser 等变体 - 纯静态托管(GitHub Pages / Vercel)无法做服务端判断,只能靠前端
别忽略微信和 QQ 内置浏览器的特殊行为
它们 UA 字符串里同时含 "MicroMessenger" 和 "Mobile",但部分安卓微信版本会把 UA 改成桌面格式(伪装成 Chrome),导致前端 UA 判断失效。
此时 matchMedia + 'ontouchstart' in window 组合更准,但要注意:Chrome 桌面版开启开发者工具模拟移动设备时,ontouchstart 也会存在。
- 简单兜底:
!!navigator.userAgent.match(/MicroMessenger/i) || !!navigator.userAgent.match(/QQ\/\d+/i) - 真机检测建议加一层:检查
screen.width < 900 && 'ontouchstart' in window,排除桌面模拟场景 - 微信 JS-SDK 的
getNetworkType不能用于设备判断,它返回的是网络类型
实际项目里,多数情况用 navigator.userAgent + matchMedia 双保险就够了。真正难处理的是那些 UA 被刻意抹除或篡改的环境,比如某些企业微信定制版、鸿蒙 WebView 的早期版本——这时候得靠用户手动切换按钮兜底。

