JS-Navigator 对象全方位实战指南

45 阅读3分钟

前言

在前端开发中,我们需要了解用户到底在用什么设备、网络状况如何、甚至物理位置在哪里。这时,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是否启用 Cookietrue
platform操作系统平台(已废弃但常用)"Win32", "MacIntel"
hardwareConcurrencyCPU 逻辑核心数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 请求有什么区别?

参考回答:

  1. 优先级sendBeacon 是为了解决页面卸载时发送数据的问题设计的,浏览器会将其放入专门的队列,即使页面已关闭,浏览器也会在后台完成发送。
  2. 不阻塞:它完全异步,不会像同步 XHR 那样阻塞页面跳转。
  3. 请求类型:只能发送 POST 请求,且无法读取服务器的响应内容(它是“射后不理”的)。

Q3:如何获取用户的剪切板内容?有什么限制?

参考回答:

使用 navigator.clipboard.readText()。

限制:

  1. 必须在 HTTPS 环境下使用。
  2. 必须由 用户交互(如点击事件)触发,不能自动读取。
  3. 浏览器通常会弹窗询问用户是否允许读取。