Web Serial API是W3C标准的浏览器原生串口接口,依赖navigator.serial对象,仅Chrome/Edge等Chromium内核浏览器支持(Chrome 109+、Edge 110+),须HTTPS(localhost除外)且用户手势触发;它提供requestPort()和getPorts()获取SerialPort实例,通过ReadableStream/WritableStream读写二进制数据,不解析协议,需自行处理帧、流控与错误恢复。

HTML 本身不能直接做串口通信——必须通过 JavaScript 调用 Web Serial API,且仅在支持该 API 的浏览器(如 Chrome 109+、Edge 110+)中可用,不支持 Safari 和 Firefox。
Web Serial API 是什么,为什么非它不可
Web Serial 是浏览器提供的原生串口访问接口,绕过了传统需要 Electron/Node.js + native 插件的方案。它不是 HTML 标签或属性,而是 JavaScript 运行时能力,依赖 navigator.serial 全局对象。没有它,<input> 或 <form></form> 标签对串口毫无作用。
- 必须在 HTTPS 环境下运行(
localhost除外) - 必须由用户手势触发(比如点击按钮),不能自动连接
- 不提供“虚拟 COM 口列表”自动枚举——需调用
serial.getPorts()或serial.requestPort() - 返回的是
SerialPort实例,不是字符串或 URL
requestPort() 和 getPorts() 的区别与选用场景
两者都返回 SerialPort 对象,但行为和权限要求不同:
-
serial.requestPort():弹出系统选择框,让用户手动选设备;首次调用会请求持久化访问权限(可勾选“记住此选择”) -
serial.getPorts():只返回之前已授权且仍连接的端口,适合热插拔后快速重连,但无法发现新设备 - 生产环境建议先用
getPorts()尝试恢复连接,失败再 fallback 到requestPort()
示例逻辑:
立即学习“前端免费学习笔记(深入)”;
let port;
async function connect() {
try {
// 先查已授权端口
const ports = await navigator.serial.getPorts();
if (ports.length > 0) port = ports[0];
else port = await navigator.serial.requestPort(); // 用户选择
await port.open({ baudRate: 9600 });
} catch (err) {
console.error("串口打开失败:", err.message);
}
}
read() 和 write() 容易卡死的几个关键点
Web Serial 的读写是基于 ReadableStream 和 WritableStream 的流式操作,不是同步函数调用,不处理好就会无响应或丢数据:
-
port.readable可能为null—— 必须在port.open()成功后再获取,且需检查是否已关闭 -
read()不会自动循环:需手动用while+await reader.read()持续读取,否则只读一次就停 -
write()接收Uint8Array,不是字符串;发送"AT\r\n"要先转成new TextEncoder().encode("AT\r\n") - 没调用
reader.cancel()或reader.releaseLock(),下次读会报TypeError: ReadableStreamDefaultReader is already reading
常见错误信息及对应修复
遇到这些提示,基本可以定位到具体环节:
-
SecurityError: Permission denied→ 页面非 HTTPS(或非 localhost),或未由用户点击触发 -
NotFoundError: No port selected→requestPort()被用户取消,或getPorts()返回空数组且没 fallback -
NetworkError: Port is not open→ 在port.open()前就调用了read()或write() -
TypeError: Failed to execute 'write' on 'WritableStream': stream is locked→ 多个地方同时调用writer.write(),没加锁或排队
真正麻烦的从来不是“怎么连上”,而是“连上之后怎么稳住读写节奏、正确解析帧、处理断连重试”。流控制、超时判断、粘包分包,这些得自己补全——Web Serial 只负责把字节送进送出,不帮你理解协议。



















