You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ElectronJS无法连接串口求助:Angular应用浏览器正常Electron报错

解决方案:Electron中调用Web Serial API报错NotFoundError

问题原因

Electron对Web Serial API的支持逻辑与浏览器存在差异,主要涉及权限配置、上下文隔离限制、用户手势触发要求这几个方面,直接复用浏览器中的代码会导致无法弹出设备选择窗口或触发报错。

具体解决步骤

1. 配置BrowserWindow确保API支持

Electron 12及以上版本原生支持Web Serial API,旧版本需手动启用实验特性。在主进程的BrowserWindow配置中添加如下设置:

const { BrowserWindow } = require('electron');
const path = require('path');

const mainWindow = new BrowserWindow({
  webPreferences: {
    // Electron 12-18版本需启用此配置,新版本可省略
    experimentalFeatures: true,
    // 上下文隔离为默认启用状态,需通过预加载脚本桥接API
    contextIsolation: true,
    preload: path.join(__dirname, 'preload.js')
  }
});

2. 编写预加载脚本暴露Serial接口

由于上下文隔离限制,渲染进程无法直接访问navigator.serial,需通过预加载脚本桥接:

// preload.js
const { contextBridge } = require('electron');

contextBridge.exposeInMainWorld('electronSerial', {
  requestPort: async () => {
    try {
      return await navigator.serial.requestPort();
    } catch (err) {
      throw err;
    }
  }
});

3. 修改Angular组件的connect方法

替换原有调用逻辑,使用预加载脚本暴露的接口:

async connect() {
  if (!this.port) {
    try {
      this.port = await window.electronSerial.requestPort();
    } catch (err) {
      console.error('Requesting port error:', err);
    }
  }
}

4. 确保调用触发自用户手势

Web Serial API要求必须由用户交互(如点击按钮)触发,否则会被拦截。确保connect方法绑定到用户点击事件:

<!-- Angular组件模板 -->
<button (click)="connect()">连接设备</button>

5. 备选方案:使用第三方serialport库

若Web Serial API仍存在兼容性问题,可使用Electron生态的serialport库,通过主进程处理串口操作,IPC通信传递结果:

  • 安装依赖:npm install serialport
  • 主进程代码:
const { ipcMain } = require('electron');
const SerialPort = require('serialport');

// 获取串口列表
ipcMain.handle('serial:get-ports', async () => {
  return await SerialPort.list();
});

// 连接指定串口
ipcMain.handle('serial:connect', async (_, portPath) => {
  const port = new SerialPort({ path: portPath, baudRate: 9600 });
  return port.path;
});
  • Angular组件代码:
import { ipcRenderer } from 'electron';

async connect() {
  if (!this.port) {
    try {
      const ports = await ipcRenderer.invoke('serial:get-ports');
      // 自定义弹窗让用户选择端口
      const selectedPort = await this.selectPort(ports);
      this.port = await ipcRenderer.invoke('serial:connect', selectedPort.path);
    } catch (err) {
      console.error('连接失败:', err);
    }
  }
}

内容的提问来源于stack exchange,提问作者Katerina Maria Gerakianaki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 23:25:34