Chrome扩展中Web Serial API调用requestPort报错求助
Chrome扩展中Web Serial API requestPort()报错:No port selected by the user
我们开发一款Chrome扩展(Manifest V3),通过Web Serial API与微控制器通信。扩展弹窗中的按钮点击后本该唤起串口选择器,却直接抛出错误:
Uncaught (in promise) DOMException: Failed to execute 'requestPort' on 'Serial': No port selected by the user.
在普通标签页控制台执行navigator.serial.requestPort()可正常弹出选择框,但在扩展控制台或弹窗脚本中执行就报错。
问题原因
- 缺少Serial权限声明:Manifest V3中使用Web Serial API必须显式在
permissions数组中添加"serial"权限,否则扩展无权限调用该API,错误表现为"用户未选择端口"。 - 未处理用户取消操作:即使权限正确,若用户在串口选择器中点击取消,
requestPort()也会抛出该异常,需要捕获处理。
解决方案
1. 更新manifest.json添加Serial权限
在permissions数组中加入"serial"权限:
{ "manifest_version": 3, "name": "COI", "description": "Control the COI Computerized Oblique Illumination Device", "version": "0.1", "background": { "service_worker": "background.js" }, "options_page": "options.html", "action": { "default_popup": "popup/popup.html", "default_icon": "images/icon.png" }, "permissions": [ "storage", "activeTab", "scripting", "tabs", "serial" // 添加Serial权限 ] }
2. 优化弹窗脚本的错误处理
修改window.js,添加异常捕获逻辑,并直接复用选中的端口:
onload = function() { document.getElementById("connect-button").addEventListener('click', async () => { console.log("Connect button clicked"); try { // 请求用户选择串口 const selectedPort = await navigator.serial.requestPort(); console.log("Port selected:", selectedPort); // 获取所有已授权的串口 const authorizedPorts = await navigator.serial.getPorts(); console.log("Authorized ports:", authorizedPorts); buildPortPicker(authorizedPorts); openSelectedPort(selectedPort); // 直接传入已选中的端口 } catch (error) { // 区分用户取消和其他错误 if (error.name === "NotFoundError") { console.log("User canceled port selection"); } else { console.error("Port request failed:", error); } } console.log("Port selection workflow finished"); }); }
额外说明
- Web Serial API必须由用户交互触发(如按钮点击),你的代码已符合该要求,无需调整。
- 若问题仍存在,可尝试将串口操作逻辑移至Background Service Worker,但弹窗中直接调用在权限配置正确的情况下完全可行。
内容的提问来源于stack exchange,提问作者Joseph Freeston
相关产品推荐
相关产品推荐

