Flutter升级后dart:html废弃,如何用package:web改写文件下载代码?
用package:web替代dart:html实现Web端资产文件下载
升级Flutter后收到提示,需使用package:web和dart:js_interop替代已废弃的dart:html。现有一段基于dart:html实现的Web端资产文件下载代码,尝试将List<int>转换为JSArray来创建Blob时失败,以下是修正方案:
原代码
import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/services.dart' show ByteData, rootBundle; import 'dart:html' as html; Future<void> downloadCV() async { // 检查是否为Web环境 if (!kIsWeb) { return; } try { // 加载资产文件 const String assetPath = 'assets/xx_file.pdf'; final ByteData data = await rootBundle.load(assetPath); final List<int> bytes = data.buffer.asUint8List(); // 从数据创建Blob final blob = html.Blob([bytes], 'application/pdf'); final url = html.Url.createObjectUrlFromBlob(blob); // 创建隐藏的<a>标签触发下载 final anchor = html.AnchorElement(href: url) // 设置文件名 ..setAttribute("download", "xx_file.pdf") ..click(); // 释放对象URL html.Url.revokeObjectUrl(url); print("文件下载已启动。"); } catch (e) { print('文件下载错误: $e'); } }
错误的转换尝试
// 尝试用web包创建Blob并将List<int>转为JSArray final blob = web.Blob([bytes.toJS].toJS, web.BlobPropertyBag(type: 'application/pdf'));
修正后的完整代码
import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/services.dart' show ByteData, rootBundle; import 'package:web/web.dart' as web; import 'dart:js_interop'; import 'dart:typed_data'; Future<void> downloadCV() async { if (!kIsWeb) { return; } try { const String assetPath = 'assets/xx_file.pdf'; final ByteData data = await rootBundle.load(assetPath); final List<int> bytes = data.buffer.asUint8List(); // 将Dart的List<int>转为JS的Uint8Array,再包装成JSArray传入Blob final jsUint8Array = Uint8List.fromList(bytes).toJS; final blob = web.Blob([jsUint8Array].toJS, web.BlobPropertyBag(type: 'application/pdf')); final url = web.URL.createObjectURL(blob); // 创建并触发下载链接 final anchor = web.HTMLAnchorElement() ..href = url ..download = "xx_file.pdf" ..click(); web.URL.revokeObjectURL(url); print("文件下载已启动。"); } catch (e) { print('文件下载错误: $e'); } }
关键修正说明
- 必须引入
dart:js_interop和dart:typed_data来完成Dart与JS类型的正确转换 - 不能直接调用
bytes.toJS,需要先把Dart的List<int>转为Uint8List,再通过.toJS得到JS原生的Uint8Array,这才是Blob支持的二进制数据格式 web.Blob的第一个参数需要是包含二进制数据的JSArray,因此用[jsUint8Array].toJS完成转换- API名称有细微调整:原
html.Url对应web.URL,原html.AnchorElement对应web.HTMLAnchorElement
内容的提问来源于stack exchange,提问作者Ashikul Islam Sawan
相关产品推荐
相关产品推荐

