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

如何通过URL直接下载图片而非在新标签页中打开

解决方案(适配Flutter Web场景)

方案1:同源图片资源直接下载

无需额外请求资源,直接通过浏览器锚点API触发下载:

import 'dart:html' as html;

void downloadImage(String imageUrl, String saveFileName) {
  final anchor = html.AnchorElement(href: imageUrl)
    ..setAttribute('download', saveFileName)
    ..target = '_self';
  html.document.body?.append(anchor);
  anchor.click();
  anchor.remove();
}

方案2:跨域图片资源流下载

先以二进制流形式拉取资源,再触发浏览器下载,不会打开新标签页:

import 'dart:html' as html;
import 'package:dio/dio.dart';

Future<void> downloadNetworkImage(String imageUrl, String saveFileName) async {
  // 以blob流形式请求资源,不会触发页面跳转
  final response = await Dio().get(
    imageUrl,
    options: Options(responseType: ResponseType.blob),
  );
  final blob = html.Blob([response.data]);
  final tempUrl = html.Url.createObjectUrlFromBlob(blob);
  // 触发下载
  final anchor = html.AnchorElement(href: tempUrl)
    ..setAttribute('download', saveFileName)
    ..target = '_self';
  html.document.body?.append(anchor);
  anchor.click();
  // 清理临时资源避免内存泄漏
  html.Url.revokeObjectUrl(tempUrl);
  anchor.remove();
}

原有方案失效原因说明

  • url_launcher/url_launcher_web的默认逻辑是调用浏览器访问目标链接,如果服务端未返回Content-Disposition: attachment响应头,浏览器会直接预览图片而非下载,还会触发新标签页打开
  • 原有dio写法是桌面/移动端的文件写入逻辑,Web端没有直接写入本地文件系统的权限,需要走浏览器原生下载机制实现

注意事项

如果是跨域资源,需要资源所在的服务端配置CORS规则,允许你的站点域名请求资源,否则会触发跨域拦截无法拉取blob流。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 21:54:02