Flutter Web中如何访问window.navigator.serial对象?
可以手动扩展dart:html的Navigator对象来添加serial属性支持,也可以直接通过dart:js_util动态访问该属性,两种方案都可以在Flutter Web中正常使用。
方法1:扩展Navigator类(类型安全,推荐)
通过package:js的JS interop能力扩展现有Navigator类,提前定义好Web Serial API的相关类型,调用时可以获得IDE的类型提示和语法检查。
- 首先导入依赖包:
import 'dart:html'; import 'dart:js_util'; import 'package:js/js.dart';
- 定义JS interop绑定:
@JS() library web_serial; // 扩展现有Navigator类添加serial属性 @JS('Navigator') abstract class SerialNavigator extends Navigator { external Serial get serial; } // 定义Serial API的核心接口,可根据实际使用的API补充方法/属性 @JS() abstract class Serial { external Future<SerialPort> requestPort([RequestPortOptions? options]); external Future<List<SerialPort>> getPorts(); } // 按需补充SerialPort、RequestPortOptions等相关接口定义 @JS() abstract class SerialPort { external Future<void> open(SerialOptions options); external ReadableStream get readable; external WritableStream get writable; external Future<void> close(); } @JS() @anonymous abstract class RequestPortOptions { external factory RequestPortOptions({List<Map>? filters}); external List<Map> get filters; } @JS() @anonymous abstract class SerialOptions { external factory SerialOptions({int baudRate, int dataBits = 8, int stopBits = 1, String parity = 'none'}); external int get baudRate; }
- 调用示例:
// 先判断当前浏览器是否支持Serial API if (hasProperty(window.navigator, 'serial')) { final serial = (window.navigator as SerialNavigator).serial; // 示例:获取已授权的串口列表 final ports = await serial.getPorts(); // 示例:请求用户选择串口 final selectedPort = await serial.requestPort(RequestPortOptions(filters: [])); } else { // 不支持的浏览器给出提示 print('当前浏览器不支持Web Serial API,请使用Chrome/Edge浏览器'); }
方法2:动态调用(无需提前定义类型,适合简单场景)
如果只需要调用少量Serial API,不需要完整的类型提示,可以直接用dart:js_util的方法动态访问属性、调用方法:
import 'dart:html'; import 'dart:js_util'; if (hasProperty(window.navigator, 'serial')) { // 获取serial对象 final serial = getProperty(window.navigator, 'serial'); // 调用getPorts方法,注意要把JS Promise转成Dart Future final ports = await promiseToFuture(callMethod(serial, 'getPorts', [])); // 调用requestPort方法 final selectedPort = await promiseToFuture(callMethod(serial, 'requestPort', [ jsify({'filters': []}) ])); }
注意事项
- Web Serial API仅在安全上下文(HTTPS协议、localhost本地调试)下可用,非安全上下文会无法访问serial属性
requestPort方法必须由用户交互事件(如按钮点击、手势操作)触发,否则浏览器会直接拦截请求- 生产环境必须先做属性存在性判断,避免在Safari等不支持该API的浏览器中出现运行时报错
内容的提问来源于stack exchange,提问作者xerotolerant
相关产品推荐
相关产品推荐

