跳转到内容

Web Serial API:navigator.serial 串口访问

发布于 更新于

一句话: Web Serial API 让页面通过 navigator.serial.requestPort() 请求用户选择一个 串口,然后通过返回的 SerialPort 的 readable/writable 流读写字节。MDN 将 Serial 接口标记为非 Baseline——“because it does not work in some of the most widely-used browsers”(因为它在一些广泛使用的浏览器中无法工作)——并且只在安全上下文中暴露。

const port = await navigator.serial.requestPort();
await port.open({ baudRate: 9600 });

根据 MDN,requestPort() “must be called via transient activation”(必须通过用户激活调用) ——应在点击事件等用户手势中触发,而不是在页面加载时自动调用。navigator.serial.getPorts() 会返回当前已连接、且该源已拥有访问权限的端口组成的数组,而不会再次弹出提示:

const ports = await navigator.serial.getPorts();

访问也可能被 serial 权限策略(Permissions Policy)阻止;根据 MDN,被阻止的页面不会显示 设备选择器,用户也不会看到提示。

  • 图例
  • 支持
  • 部分支持
  • 需开启标志
  • 不支持
  • 未知
浏览器 / 平台支持版本置信度来源备注
Chrome (Desktop)支持89高来源—
Chrome (Android)支持148高来源—
Edge (Desktop)支持89高来源1
Firefox (Desktop)支持151高来源—
Firefox (Android)不支持—高来源2
Safari (macOS)不支持—高来源3
Safari (iOS)不支持—高来源45
Samsung Internet部分支持30.0高来源67
WebView (Android)不支持—高来源8
  1. 由 browser-compat-data 镜像自 Chrome 的数据推导。
  2. browser-compat-data 未记录 Firefox for Android 的支持。
  3. browser-compat-data 未记录 Safari 的支持。
  4. browser-compat-data 未记录 iOS 版 Safari 的支持。
  5. 由 browser-compat-data 镜像自 Safari 的数据推导。
  6. 仅当串口由蓝牙 RFCOMM 串口仿真提供时才可用。
  7. 由 browser-compat-data 镜像自 Chrome Android 的数据推导。
  8. 实现跟踪:https://crbug.com/40740509。

源数据: /compatibility/web-serial.json · 全球使用占比: 72 % (StatCounter 2026-05)

来源: 规范 · MDN · 最近核验 2026-10-03 · 置信度: 高 (由来源计算)

根据上方的兼容性数据,桌面版 Chrome 和 Edge 自 89 版起支持该 API,桌面版 Firefox 则较晚 才支持,为 151 版起。Safari 在 macOS 和 iOS 上均不支持。在 Android 上,根据 MDN 的 browser-compat-data,Chrome 自 148 版起完整支持;138–146 版的串口“are only available if they are provided by Bluetooth RFCOMM serial port emulation”(仅在由蓝牙 RFCOMM 串口仿真提供时可用)。 Firefox for Android 不支持该 API。

const reader = port.readable.getReader();
try {
while (true) {
const { value, done } = await reader.read();
if (done) break;
console.log(value);
}
} finally {
reader.releaseLock();
}

navigator.serial 还会派发 connect 与 disconnect 事件——从 SerialPort 冒泡而来 ——因此页面可以在已授权设备被接入或移除时做出响应,而不必轮询 getPorts()。

async function connectSerial() {
if (!('serial' in navigator)) {
// 此处不支持 Web Serial —— 回退到 WebUSB,或引导用户使用原生配套应用,
// 而不是调用 navigator.serial。
return null;
}
const port = await navigator.serial.requestPort();
await port.open({ baudRate: 9600 });
return port;
}
  • requestPort() 需要用户激活——应在点击事件处理函数中调用,而不是在页面加载时自动 调用,否则返回的 Promise 会被拒绝。
  • 在调用任何方法之前先做特性检测 'serial' in navigator;MDN 将 Web Serial 标记为 非 Baseline,因此某些浏览器不支持是预期情况。
  • 通过 HTTPS 提供页面——Serial 接口只在安全上下文中暴露。
  • 在 Android 上,先确认 Chrome 版本再假设能访问 USB 连接的设备——根据 MDN 的 browser-compat-data,138–146 版仅覆盖蓝牙 RFCOMM 仿真,148 起为完整支持。
  • 在加载时先调用 getPorts(),再回退到 requestPort(),以便复用此前已授权的端口 而无需再次弹出提示。
  • 页面也可能被 serial 权限策略直接阻止弹出提示——应将这种失败模式与用户主动拒绝 区分开来处理。
  • WebUSB API —— 关于未被操作系统驱动程序占用的 USB 设备的相关参考条目。
  • WebHID API —— 关于 USB HID 类输入设备的 相关参考条目。