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

Flutter Web中如何在浏览器中打开已下载的文件?

Flutter Web 下载带认证Token的文件后在新标签页打开的解决方案

由于Flutter Web没有原生临时目录,且目标文件需要携带认证Token才能请求、无法直接通过URL访问,我们可以通过Blob + Object URL的方式在内存中处理文件数据,实现新标签页打开的需求。

具体实现步骤

  1. 导入dart:html包(仅Web平台生效,借助kIsWeb做平台判断)
  2. 将下载得到的字节数据转换为浏览器可识别的Blob对象
  3. 基于Blob生成临时Object URL
  4. 在新标签页打开该URL,最后释放URL避免内存泄漏

修改后的下载函数

import 'dart:html' as html;
// 其他必要导入(如http、path_provider等)...

Future<XFile?> download({required String path, Map<String, dynamic>? queryParams}) async {
  Options options = generateOptions(await generateToken(), responseType: ResponseType.bytes);
  Map<String, String> headers = {};
  options.headers?.forEach((key, value) {
    headers[key] = '$value';
  });
  try {
    var response = await http.get(
      Uri.parse(path),
      headers: headers,
    );
    // 处理MIME类型,为空时用通用二进制类型兜底
    String mimeType = response.headers['content-type'] ?? 'application/octet-stream';
    // 从响应头提取文件名,无则用默认值
    String fileName = response.headers['content-disposition']?.split('filename=').last ?? 'File';
    String filePath = '${kIsWeb == true ? fileName : (await getTemporaryDirectory()).path}/$fileName';
    XFile file = XFile.fromData(
      response.bodyBytes,
      mimeType: mimeType,
      name: fileName,
      path: filePath,
    );

    if (!kIsWeb) {
      await File(filePath).create(recursive: true);
      await File(filePath).writeAsBytes(await file.readAsBytes());
    } else {
      // Web端核心逻辑:生成Blob并在新标签页打开
      final blob = html.Blob([response.bodyBytes], mimeType);
      final url = html.Url.createObjectUrlFromBlob(blob);
      // 新标签页打开文件
      html.window.open(url, '_blank');
      // 释放临时URL,防止内存泄漏
      html.Url.revokeObjectUrl(url);

      // 若需要同时保留下载功能,取消注释下面一行
      // await WebDownloader.downloadBase64(base64data: base64Encode(response.bodyBytes), filename: fileName);
    }
    return file;
  } catch (e) {
    errorManagement(e);
  }
  return null;
}

关键注意事项

  • MIME类型适配:如果响应头未返回content-type,可根据文件名后缀手动指定(如.pdf对应application/pdf),提升浏览器对文件的识别准确性。
  • 内存泄漏防范:必须调用html.Url.revokeObjectUrl(url)释放临时URL,避免长期运行导致浏览器内存占用过高。
  • 跨平台兼容:通过kIsWeb判断平台,确保dart:html相关代码仅在Web环境执行,不影响Android/iOS端编译运行。

内容的提问来源于stack exchange,提问作者Pandruz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 21:40:06