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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 07:57:16