Flutter Web:将GCS公开URL文件下载至本地下载文件夹的实现
Flutter Web实现GCS公开文件直接下载到本地文件夹
因为是Web应用,没法像原生那样直接操作本地文件系统,得借助浏览器的下载机制来实现。下面是具体的实现步骤,兼容Windows、iOS、Linux的主流浏览器:
核心思路
通过HTTP请求获取GCS文件的字节数据,转为浏览器可识别的Blob对象,再创建隐藏的下载链接触发浏览器的下载流程,最后清理资源。
实现步骤
添加依赖
在pubspec.yaml里加入http包,用来发起HTTP请求获取文件数据:dependencies: flutter: sdk: flutter http: ^1.1.0 # 可替换为最新版本封装下载函数
创建一个可复用的下载函数,处理从请求到触发下载的全部逻辑:import 'dart:html' as html; import 'dart:typed_data'; import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; Future<void> downloadGcsFile(String gcsUrl, String fileName) async { try { // 发起请求获取文件字节数据 final response = await http.get(Uri.parse(gcsUrl)); if (response.statusCode != 200) { throw Exception('文件获取失败,状态码:${response.statusCode}'); } // 将字节数据转为Blob(可指定MIME类型,提升兼容性) final blob = html.Blob( [response.bodyBytes], _getMimeTypeFromUrl(gcsUrl), // 可选,自动识别文件类型 ); // 创建Blob的临时URL final blobUrl = html.Url.createObjectUrlFromBlob(blob); // 创建隐藏的a标签,设置下载属性 final downloadAnchor = html.AnchorElement(href: blobUrl) ..setAttribute('download', fileName) ..style.display = 'none'; // 添加到DOM并触发点击 html.document.body?.append(downloadAnchor); downloadAnchor.click(); // 清理资源,避免内存泄漏 html.document.body?.remove(downloadAnchor); html.Url.revokeObjectUrl(blobUrl); // 可选:显示下载成功提示 ScaffoldMessenger.of(html.window.navigator.key.currentContext!) .showSnackBar(const SnackBar(content: Text('文件开始下载'))); } catch (e) { print('下载出错:$e'); // 显示错误提示 ScaffoldMessenger.of(html.window.navigator.key.currentContext!) .showSnackBar(SnackBar(content: Text('下载失败:$e'))); } } // 辅助函数:从URL提取MIME类型 String _getMimeTypeFromUrl(String url) { final extension = url.split('.').last.toLowerCase(); switch (extension) { case 'pdf': return 'application/pdf'; case 'jpg': case 'jpeg': return 'image/jpeg'; case 'png': return 'image/png'; case 'txt': return 'text/plain'; default: return 'application/octet-stream'; } }在按钮中调用
替换原来的launchUrl,直接调用上面的函数:ElevatedButton( onPressed: () { // 替换为你的GCS公开URL和想要的文件名 const gcsFileUrl = 'https://storage.googleapis.com/your-bucket/your-file.pdf'; downloadGcsFile(gcsFileUrl, '我的文件.pdf'); }, child: const Text('下载文件'), )
关键注意事项
- CORS配置:如果浏览器报跨域错误,需要给你的GCS桶配置CORS规则,允许Web应用的域名发起GET请求。示例CORS配置(在GCS控制台或通过gsutil命令设置):
[ { "origin": ["https://your-web-app-domain.com"], // 替换为你的Web域名,生产环境不要用* "method": ["GET"], "responseHeader": ["Content-Type"], "maxAgeSeconds": 3600 } ] - 浏览器兼容性:主流浏览器(Chrome、Firefox、Safari、Edge)都支持这个方法,iOS Safari需确保Blob的MIME类型正确,避免无法识别文件。
- 资源清理:一定要调用
Url.revokeObjectUrl释放临时URL,否则会造成内存泄漏。
内容的提问来源于stack exchange,提问作者Mauro Gentile
相关产品推荐
相关产品推荐

