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

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的类型提示和语法检查。

  1. 首先导入依赖包:
import 'dart:html';
import 'dart:js_util';
import 'package:js/js.dart';
  1. 定义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;
}
  1. 调用示例:
// 先判断当前浏览器是否支持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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:54:04