Web Serial API无法在普通HTML编辑器中运行,因其必须运行在HTTPS或localhost安全上下文,且navigator.serial仅在用户点击等手势触发时可用,file://协议及在线沙盒环境均不暴露该API。

不能直接在普通 HTML 编辑器(如 VS Code 内置预览、CodePen、JSFiddle)里用 Web Serial API 读取硬件数据——它需要运行在安全上下文(HTTPS 或 http://localhost),且必须由用户手势触发(比如点击按钮),编辑器的沙盒环境或非服务化预览根本不会暴露 navigator.serial。
为什么 navigator.serial 在编辑器预览里是 undefined
Web Serial API 被设计为仅在“安全上下文”中可用。浏览器会主动屏蔽所有非安全环境下的访问:
-
file://协议(双击打开 HTML 文件)→ 不支持,navigator.serial为undefined - CodePen / JSFiddle / StackBlitz 等在线编辑器 → 默认非 HTTPS 沙盒,或跨域限制,API 不可用
- VS Code Live Server 插件默认启 http://127.0.0.1:5500 → ✅ 支持(只要端口未被占用且未强制跳转 HTTP)
- 本地启动的
http://localhost:3000(如 Vite、Webpack Dev Server)→ ✅ 支持
如何让 HTML 页面真正跑通 Web Serial 读取传感器
关键不是“写在哪”,而是“跑在哪”+“怎么触发”。以下是最小可行路径:
- 用 Vite 创建空项目:
npm create vite@latest my-serial-app -- --template html,然后cd my-serial-app && npm install && npm run dev - 确保 Arduino/ESP32 固件以换行分隔发送 JSON,例如:
{"temp":24.3,"hum":62.1}\n - 在
index.html中添加按钮,并把连接逻辑绑定到click事件,不能自动执行 - 使用
TextDecoderStream+LineBreakTransformer流式解析带换行的数据包,避免粘包 - 务必在
finally块中调用reader.releaseLock(),否则下次连接会报TypeError: ReadableStream is locked
requestPort() 过滤不到你的设备?检查 VID/PID 和驱动
Arduino Uno 默认 VID=0x2341、PID=0x0043,但 clone 板或 CH340 芯片板可能不同。常见问题:
立即学习“前端免费学习笔记(深入)”;
- Windows 下设备管理器显示“未知设备”或“COM 端口(错误)”→ 驱动未装,需手动安装 CH340 或 CP210x 驱动
- macOS 上
ls /dev/tty.*看不到设备 → 可能被系统阻止,需在“系统设置 > 隐私与安全性 > 完全磁盘访问”中给终端/浏览器授权 - Linux 用户需加入
dialout组:sudo usermod -a -G dialout $USER,然后重登 - 过滤写法必须严格:USB 设备必须匹配
usbVendorId和usbProductId,缺一不可;若不确定,先不加filters,靠用户手动选
高频传感器数据导致页面卡顿?别在主线程 decode + update DOM
每秒发 10 条 JSON 数据,主线程连续 JSON.parse() + innerHTML 更新图表,很快就会掉帧。实际要做的:
- 用
TransformStream把原始Uint8Array流切分成完整行,再交给 Worker 处理解析 - 前端接收后只存最近 200 条数据点,用
requestIdleCallback批量更新 Chart.js 图表 - 禁用
console.log输出(尤其在循环中),它在 Chrome 里对性能影响远超预期 - 断开时记得
reader.cancel()+port.close(),否则端口可能被锁死,需重启浏览器
真正难的不是写那几行 await port.open(),而是让整个链路在真实设备、真实操作系统、真实用户操作下稳定跑通——驱动、权限、流控、编码、节流,漏掉任一环,串口就只是个摆设。



















