Web Serial API 完全指南:浏览器串口通信实战教程

前言:浏览器也能访问串口了!

传统串口调试需要安装专用软件(如 SecureCRT、Putty),不仅麻烦,还容易遇到版本兼容问题。Web Serial API 的出现,让浏览器直接访问串口成为现实——无需安装软件,打开网页即可调试!

本文将详细介绍 Web Serial API 的方方面面,帮助你快速上手浏览器串口通信。


一、Web Serial API 浏览器支持情况

1. Chrome 版本支持

Web Serial API 从 Chrome 89 开始正式支持(2021年3月发布)。

Chrome 版本 支持状态 发布时间
Chrome 78-88 不支持 2019-2021
Chrome 89+ ✅ 完全支持 2021年3月
Chrome 89-120 稳定版本 2021-2024
Chrome 121+ 最新优化 2024至今

2. 其他浏览器支持

浏览器 支持状态 备注
Chrome 89+ ✅ 完全支持 最推荐
Edge 89+ ✅ 完全支持 Chromium内核
Opera 77+ ✅ 支持 Chromium内核
Firefox ❌ 不支持 暂无计划
Safari ❌ 不支持 暂无计划
IE ❌ 不支持 已废弃

推荐浏览器:Chrome 89+ 或 Edge 89+(最新版本)


二、Web Serial API 使用条件(必看避坑指南)

⚠️ 条件 1:必须是 HTTPS 安全上下文

这是最重要的限制!

Web Serial API 只能在安全上下文中使用:

环境 是否支持 示例
HTTPS 网站 ✅ 支持 https://example.com
localhost ✅ 支持 http://localhost:3000
HTTP 网站 不支持 http://example.com
file:// 协议 ❌ 不支持 file:///path/to/file.html

避坑提示

  • 生产环境必须使用 HTTPS
  • 本地开发可用 localhost(无需 HTTPS)
  • 如果你访问 HTTP 网站,浏览器会直接报错

⚠️ 条件 2:必须通过用户手势触发

不能自动打开串口,必须由用户点击按钮触发:

1
2
3
4
5
6
7
8
9
// ❌ 错误:页面加载时自动请求串口
window.onload = async () => {
const port = await navigator.serial.requestPort() // 会失败!
}

// ✅ 正确:用户点击按钮后请求
button.onclick = async () => {
const port = await navigator.serial.requestPort() // 成功!
}

原因:浏览器要求用户明确授权,防止恶意网站自动访问串口设备。

⚠️ 条件 3:浏览器必须启用 Web Serial API

Chrome 默认启用,但某些企业环境可能禁用。检查方法:

1
2
3
4
5
if ('serial' in navigator) {
console.log('Web Serial API 已启用')
} else {
console.log('浏览器不支持 Web Serial API')
}

三、Web Serial API 技术对接详解

1. 检测 API 支持

1
2
3
4
5
6
7
8
9
10
11
12
13
// 检查安全上下文
if (!window.isSecureContext) {
alert('需要 HTTPS 或 localhost 环境')
return
}

// 检查 API 支持
if (!('serial' in navigator)) {
alert('请使用 Chrome 89+ 或 Edge 89+')
return
}

console.log('✅ Web Serial API 可用')

2. 请求串口设备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
async function connectSerial() {
try {
// 弹出设备选择对话框
const port = await navigator.serial.requestPort()

// 获取设备信息
const info = port.getInfo()
console.log('USB Vendor ID:', info.usbVendorId)
console.log('USB Product ID:', info.usbProductId)

return port
} catch (e) {
if (e.name === 'NotFoundError') {
console.log('用户取消了选择')
} else {
console.error('请求串口失败:', e.message)
}
}
}

3. 打开串口连接

1
2
3
4
5
6
7
8
9
10
11
async function openPort(port, baudRate = 115200) {
await port.open({
baudRate: baudRate, // 波特率
dataBits: 8, // 数据位(7 或 8)
stopBits: 1, // 停止位(1 或 2)
parity: 'none', // 校验位(none/even/odd)
flowControl: 'none' // 流控制(none/hardware)
})

console.log(`串口已打开: ${baudRate} baud`)
}

4. 读取串口数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
async function readData(port) {
const decoder = new TextDecoderStream()
port.readable.pipeTo(decoder.writable)

const reader = decoder.readable.getReader()

while (port.readable) {
try {
const { value, done } = await reader.read()
if (done) break

console.log('收到数据:', value)
// 处理接收的数据...
} catch (e) {
console.error('读取错误:', e)
break
}
}

reader.releaseLock()
}

5. 发送串口数据

1
2
3
4
5
6
7
8
9
10
11
async function sendData(port, text) {
const encoder = new TextEncoder()
const writer = port.writable.getWriter()

try {
await writer.write(encoder.encode(text + '\r\n'))
console.log('发送成功:', text)
} finally {
writer.releaseLock()
}
}

6. 关闭串口连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
async function closePort(port, reader) {
try {
// 先取消读取器
await reader.cancel()
reader.releaseLock()

// 关闭串口
await port.close()

console.log('串口已关闭')
} catch (e) {
console.error('关闭失败:', e)
}
}

四、实战案例:好工具啊在线串口调试工具

好工具啊网站实现了两款强大的在线串口调试工具,完全基于 Web Serial API:

工具 1:串口调试助手

🔗 在线使用https://www.haogongjua.cn/tool/serial-debugger/

核心功能

  • ✅ 实时串口通信(收发数据)
  • ✅ AT 指令预设(ESP8266、SIM 4G 模块)
  • ✅ 发送历史记录(自动保存)
  • ✅ 定时发送功能
  • ✅ HEX/文本模式切换
  • ✅ 自定义场景管理

技术实现亮点

  1. 串口配置完整支持
1
2
3
4
5
6
7
await port.open({
baudRate: config.baudRate,
dataBits: config.dataBits, // 7 或 8
stopBits: config.stopBits, // 1 或 2
parity: config.parity, // none/even/odd
flowControl: config.flowControl === 'hardware' ? 'hardware' : undefined
})
  1. Latin1 解码避免数据丢失
1
2
// 使用 latin1 解码,每个字节直接映射到字符
const text = new TextDecoder('latin1').decode(value)
  1. 历史记录自动保存
1
2
// 保存到 localStorage,自动去重
const saved = localStorage.getItem('serial-debugger-history-items')
  1. AT 指令场景预设
  • ESP8266:WiFi 连接、TCP通信等指令
  • SIM 4G:网络注册、SMS 发送等指令

工具 2:串口数据绘图工具

🔗 在线使用https://www.haogongjua.cn/tool/serial-plotter/

核心功能

  • ✅ 实时数据可视化(Chart.js)
  • ✅ 多通道数据绘制
  • ✅ 可拖拽图表面板
  • ✅ 数据导出为 CSV
  • ✅ 终端显示模式

技术实现亮点

  1. 数据解析智能识别
1
2
3
4
5
6
7
8
9
10
// 支持两种格式:
// 1. 逗号分隔: "1.23,4.56,7.89" → col0, col1, col2
// 2. 命名通道: "speed:1.23,rpm:4567" → speed, rpm
function parseLine(line: string) {
const named = line.match(/([A-Za-z_]\w*)\s*[:=]\s*(-?\d+(?:\.\d+)?)/g)
if (named) return named.map(...)

const nums = line.split(/[,\t ]+/).map(Number)
return nums.map((value, i) => ({ name: `col${i}`, value }))
}
  1. Chart.js 实时渲染
1
2
3
4
5
6
7
8
9
10
11
// 使用定时器推送新数据到图表
setInterval(() => {
const newSamples = store.samples.slice(lastIdx, count)
for (const ds of chart.data.datasets) {
for (const { time, values } of newSamples) {
const v = values.get(ds.label)
if (v !== undefined) pts.push({ x: time, y: v })
}
}
chart.update('none')
}, 60)
  1. React-Rnd 可拖拽面板
1
2
3
4
5
6
7
8
9
<Rnd
position={{ x: config.x, y: config.y }}
size={{ width: config.width, height: config.height }}
onDragStop={(_, d) => onUpdate(config.id, { x: d.x, y: d.y })}
onResizeStop={...}
minWidth={300}
minHeight={220}
bounds="parent"
>

五、在线串口调试助手使用指南

步骤 1:打开工具页面

访问:在线串口调试助手

步骤 2:选择串口设备

点击「选择串口」按钮,浏览器会弹出设备选择对话框:

选择串口设备

  • 选择你的串口设备(如 USB-TTL 转换器)
  • 确认后点击「连接」

步骤 3:配置串口参数

默认配置:

  • 波特率:115200(常用)
  • 数据位:8
  • 停止位:1
  • 校验位:无

根据你的设备调整参数(如 Arduino Uno 用 9600)。

步骤 4:发送和接收数据

发送数据

  • 在输入框输入文本(如 AT
  • 点击「发送」或按 Enter
  • 勾选 +CR/LF 自动添加换行

接收数据

  • 右侧消息区实时显示接收内容
  • 蓝色 = 发送,灰色 = 接收,黄色 = 系统消息

步骤 5:使用 AT 指令预设

切换场景快速发送常用指令:

ESP8266 场景

  • AT - 测试连接
  • AT+GMR - 查看版本
  • AT+CWLAP - 扫描 WiFi

SIM 4G 场景

  • AT+CSQ - 查信号强度
  • AT+CREG? - 网络注册状态

六、常见问题与避坑指南

Q1: 为什么打开工具后提示”浏览器不支持 Web Serial API”?

原因:使用了不支持的浏览器(Firefox/Safari)

解决:切换到 Chrome 89+ 或 Edge 89+

Q2: 为什么点击”选择串口”后没有反应?

原因

  1. 页面不是 HTTPS 或 localhost
  2. 浏览器权限被禁用

解决

  • 确保使用 HTTPS 网站
  • 检查 Chrome 设置:chrome://settings/content/serialPorts

Q3: 为什么连接串口后无法读取数据?

原因

  1. 波特率不匹配
  2. 数据位/停止位配置错误
  3. 设备未正常工作

解决

  • 检查设备说明书确认波特率
  • 尝试常见波特率:9600、115200、57600
  • 使用设备管理器确认串口正常

Q4: 为什么发送数据后设备无响应?

原因

  1. 未添加换行符(很多设备需要 \r\n
  2. HEX 模式发送格式错误
  3. 设端未正确初始化

解决

  • 勾选 +CR/LF 自动添加换行
  • HEX 格式必须是偶数位(如 0102,不能是 01
  • 检查设备端程序是否正常运行

Q5: 多个标签页可以同时访问同一串口吗?

答案:❌ 不可以

Web Serial API 限制:一个串口只能被一个页面占用。

解决:关闭其他标签页的串口连接后再尝试。


七、Web Serial API 应用场景

1. IoT 开发调试

  • ESP8266/ESP32 WiFi 模块调试
  • Arduino 项目开发
  • STM32 固件烧录

2. 硬件测试

  • USB-TTL 串口测试
  • 传感器数据采集
  • GPS 模块调试

3. 工业设备监控

  • PLC 数据采集
  • 工控设备通信
  • 传感器实时监控

4. 教学演示

  • 串口通信原理演示
  • 嵌入式开发教学
  • 网络通信实验

八、Web Serial API 的优势与局限

优势

无需安装软件 - 浏览器原生支持
跨平台兼容 - Windows/macOS/Linux
即时使用 - 打开网页即可调试
自动更新 - 浏览器更新自动获得新特性
安全性高 - 用户授权机制防止恶意访问

局限

浏览器限制 - 仅 Chrome/Edge 支持
HTTPS 要求 - 生产环境必须 HTTPS
单实例限制 - 一个串口只能被一个页面占用
用户授权 - 每次连接需要用户确认
性能限制 - 大数据量时不如专用软件


九、总结

Web Serial API 为浏览器串口通信打开了新大门,让串口调试从”安装软件”变为”打开网页”。

核心要点回顾

  1. Chrome 89+ 是唯一推荐浏览器
  2. HTTPS 环境必须,localhost 可用 HTTP
  3. 用户手势触发,不能自动连接
  4. 配置参数匹配,波特率最关键
  5. 换行符处理,勾选 +CR/LF 最简单

推荐工具


作者:小西
更新日期:2026-06-18
本文首发于:小西的技术笔记

参考资料