Web Serial API实战指南:在浏览器中实现串口通信

发布于:2025-08-03 ⋅ 阅读:(11) ⋅ 点赞:(0)

使用Web Serial API在浏览器中实现串口通信

在这里插入图片描述

🌐 我的个人网站:乐乐主题创作室

1. 背景与概述

在现代Web应用中,与硬件设备直接通信的需求日益增长。传统上,浏览器出于安全考虑限制了与本地硬件的交互能力,但W3C推出的Web Serial API打破了这一限制,允许网页应用通过JavaScript与串行端口设备进行通信。

Web Serial API的出现使得以下场景成为可能:

  • 工业控制系统的Web界面
  • 物联网设备的配置工具
  • 嵌入式设备的调试接口
  • 3D打印机控制面板
  • 科学仪器的数据采集

2. Web Serial API简介

Web Serial API是W3C制定的标准,目前处于工作草案阶段,但已被Chrome、Edge等基于Chromium的浏览器实现。它提供了一组JavaScript接口,允许网页安全地与串行设备交互。

2.1 兼容性检查

在使用API前,应先检查浏览器支持情况:

if (!('serial' in navigator)) {
   
   
  console.error('Web Serial API is not supported in this browser');
  // 提供备用方案或提示用户更换浏览器
}

2.2 安全限制

出于安全考虑,Web Serial API有以下限制:

  1. 只能通过用户手势(如点击)触发API调用
  2. 需要用户明确选择设备
  3. 仅在安全上下文(HTTPS或localhost)中可用

3. 核心实现步骤

3.1 请求端口访问权限

async function requestPort() {
   
   
  try {
   
   
    // 请求用户选择串口设备
    const port = await navigator.serial.requestPort();
    console.log('Port selected:', port.getInfo());
    return port;
  } catch (err) {
   
   
    console.error('Error selecting port:', err);
    throw err;
  }
}

3.2 打开并配置串口

async function openPort(port, options = {
    
    }) {
   
   
  try {
   
   
    // 默认配置参数
    const defaultOptions = {
   
   
      baudRate: 9600,
      dataBits: 8,
      parity: 'none',
      stopBits: 1,
      bufferSize: 255,
      flowControl: 'none'
    };
    
    const mergedOptions = {
   
   ...defaultOptions, ...options};
    
    // 打开端口
    await port.open(mergedOptions);
    
    console.log('Port opened with options:', mergedOptions);
    return port;
  } catch (err) {
   
   
    console.error('Error opening port:', err);
    throw err;
  }
}

3.3 数据读写实现

写入数据
async function writeToPort(port, data) {
   
   
  const writer = port.writable.getWriter();
  
  try {
   
   
    // 如果数据是字符串,转换为Uint8Array
    if (typeof data === 'string') {
   
   
      const encoder = new TextEncoder();
      data = encoder.encode(data);
    }
    
    await writer.write(data);
    console.log('Data written:', data);
  } catch (err) {
   
   
    console.error('Write error:', err);
    throw err;
  } finally {
   
   
    writer.releaseLock();
  }
}
读取数据
async function readFromPort(port, callback) {
   
   
  const reader = port.readable.getReader();
  
  try {
   
   
    while (true) {
   
   
      const {
   
    value, done } = await reader.read();
      if (done) {
   
   
        console.log('Stream closed');
        break;
      }
      
      // 处理接收到的数据
      if (callback