前言
在前端开发中,我们需要了解用户到底在用什么设备、网络状况如何、甚至物理位置在哪里。这时,navigator 对象就是我们派出的“侦探”。它存储了浏览器的版本、操作系统、设备能力等关键信息。今天我们就来盘点 navigator 中那些高频使用的核心技能。
一、 核心身份识别:UserAgent
navigator.userAgent 是实战中用来判断设备类型(iOS/Android/PC)的基石。
// 简单的设备判断函数
const isMobile = /Mobi|Android|iPhone/i.test(navigator.userAgent);
console.log(isMobile ? "当前是移动端" : "当前是 PC 端");
注意:随着隐私保护加强,现代浏览器正在推广 User-Agent Client Hints (
navigator.userAgentData) 来逐步替代userAgent。
二、 现代 API 实战(高频场景)
navigator 不仅仅是用来读属性的,它还挂载了许多强大的 API。
1. 剪切板操作:Clipboard API
早期的 document.execCommand 已被废弃,现代复制粘贴使用 navigator.clipboard,它是异步的。
// 复制文本到剪切板
async function copyText(text) {
try {
await navigator.clipboard.writeText(text);
console.log('复制成功!');
} catch (err) {
console.error('复制失败: ', err);
}
}
// 读取剪切板内容
async function readText() {
const text = await navigator.clipboard.readText();
console.log('剪切板内容:', text); // text为复制到剪切板上内容
}
2. 页面卸载时的“遗言”:sendBeacon
面试必考点:如何在页面关闭(unload)前可靠地发送埋点数据?
使用 XHR 或 Fetch 可能会因为页面关闭而被浏览器取消,使用同步 AJAX 会阻塞页面关闭影响体验。sendBeacon 是最佳解。
- 特点:异步发送、不阻塞页面关闭、但是不一定保证发送成功!!!
// 页面卸载时发送数据
window.addEventListener('unload', function() {
const data = JSON.stringify({ event: 'page_close', time: Date.now() });
// 注意:如果后端需要 JSON 格式,建议使用 Blob 设置 Header
const blob = new Blob([data], { type: 'application/json' });
const result = navigator.sendBeacon('/api/log', blob);
console.log(result ? "埋点进入发送队列" : "发送队列已满");
});
3. 地理位置:Geolocation
获取用户经纬度,常用于地图或本地服务。
- 注意:必须在 HTTPS 环境下才能调用,且需要用户授权。
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(pos) => {
console.log(`维度: ${pos.coords.latitude}`);
console.log(`经度: ${pos.coords.longitude}`);
},
(err) => {
console.error("定位失败(可能是用户拒绝或超时):", err.message);
},
{ timeout: 5000 } // 设置超时时间
);
}
三、 环境嗅探属性
| 属性 | 描述 | 示例值 |
|---|---|---|
language | 浏览器首选语言 | "zh-CN" |
cookieEnabled | 是否启用 Cookie | true |
platform | 操作系统平台(已废弃但常用) | "Win32", "MacIntel" |
hardwareConcurrency | CPU 逻辑核心数 | 8 (常用于决定开启多少 Web Worker) |
四、 网络状态的“假象”:onLine
navigator.onLine 返回 true 表示设备连接到了局域网或路由器,并不代表一定能访问互联网(比如连了 wifi 但宽带欠费了)。
因此,更严谨的网络检测通常结合 window 的事件监听:
function updateStatus() {
const status = document.getElementById('status');
if (navigator.onLine) {
console.log("网络已连接(但不一定能上网)");
// 实际场景中,这里通常会发一个请求 ping 一下服务器来确认真连网
} else {
console.log("网络已断开");
}
}
// 监听网络变化事件
window.addEventListener('online', updateStatus);
window.addEventListener('offline', updateStatus);
五、 面试模拟题
Q1:如何判断当前用户是否处于断网状态?
参考回答:
初步判断可以使用 navigator.onLine 属性,配合 window 的 online 和 offline 事件监听。但 navigator.onLine 存在误报(只检测网卡连接状态),最稳妥的方式是配合一个轻量级的 Ajax 请求(Ping)或者加载一张 1x1 像素的图片来检测实际连通性。
Q2:navigator.sendBeacon 和普通 AJAX 请求有什么区别?
参考回答:
- 优先级:
sendBeacon是为了解决页面卸载时发送数据的问题设计的,浏览器会将其放入专门的队列,即使页面已关闭,浏览器也会在后台完成发送。 - 不阻塞:它完全异步,不会像同步 XHR 那样阻塞页面跳转。
- 请求类型:只能发送 POST 请求,且无法读取服务器的响应内容(它是“射后不理”的)。
Q3:如何获取用户的剪切板内容?有什么限制?
参考回答:
使用 navigator.clipboard.readText()。
限制:
- 必须在 HTTPS 环境下使用。
- 必须由 用户交互(如点击事件)触发,不能自动读取。
- 浏览器通常会弹窗询问用户是否允许读取。