Flutter Web本地文件下载正常 生产环境提示无文件如何解决
问题现象
个人网站实现点击按钮下载存放在assets文件夹的简历PDF功能,本地调试时功能完全正常,部署到生产环境后点击下载提示Failed - No file错误,相关报错截图:

原有实现代码:
- 下载函数
downloadFile(url) { AnchorElement anchorElement = AnchorElement( href: url, ); anchorElement.download = "resume.pdf"; anchorElement.click(); }
- 下载按钮逻辑
TextButton.icon( onPressed: () { downloadFile("assets/resume.pdf"); }, style: ButtonStyle( padding: MaterialStateProperty.all<EdgeInsetsGeometry>( const EdgeInsets.fromLTRB(30, 15, 30, 15)), shape: MaterialStateProperty.all<RoundedRectangleBorder>( RoundedRectangleBorder( borderRadius: BorderRadius.circular(30.0), side: const BorderSide( color: MyColors.lightBlue, width: 2))), ), icon: const Icon( Icons.sim_card_download_outlined, color: Colors.black, size: 20, ), label: Text( ResponsiveWrapper.of(context).isDesktop ? 'DOWNLOAD FULL RESUME' : 'RESUME', style: MyFonts.roundedMedium, ), ),
- pubspec.yaml资源配置
assets: - assets/placeholder.jpg - assets/profilePic.jpg - assets/resume.pdf
问题原因
核心问题是硬编码的assets/resume.pdf相对路径不符合Flutter Web生产环境的资源访问规则:
- 本地调试阶段,Flutter开发服务器默认把项目内的assets文件夹映射到服务根路径,写相对路径可以直接命中文件
- 生产构建部署后,只要站点不是挂在域名根目录(比如部署在Github Pages子路径、站点二级目录下),web目录下index.html里配置的
<base href>不是/,硬写的相对路径会直接到域名根目录找资源,必然报404;就算部署在根路径,部分CDN、静态托管服务的资源路由规则也可能导致硬编码路径无法命中文件。
修复方法
直接替换原有下载逻辑,用Flutter内置的资源读取能力加载PDF内容,转成临时Blob地址触发下载,完全不受部署路径、托管服务路由规则影响:
- 在对应组件文件头部引入需要的依赖
import 'dart:html'; import 'package:flutter/services.dart';
- 把原有按钮的onPressed逻辑替换为以下代码,不需要单独保留原来的downloadFile函数也可以
onPressed: () async { // 直接从应用构建包内读取PDF资源,不存在路径匹配问题 final pdfByteData = await rootBundle.load('assets/resume.pdf'); final pdfBytes = pdfByteData.buffer.asUint8List(); // 生成临时Blob访问地址 final blobUrl = Url.createObjectUrlFromBlob( Blob([pdfBytes], 'application/pdf') ); // 触发浏览器下载行为 AnchorElement(href: blobUrl) ..download = 'resume.pdf' ..click(); // 释放临时地址,避免不必要的内存占用 Url.revokeObjectUrl(blobUrl); },
补充说明:如果不想用转Blob的实现方式,也可以手动读取当前页面的base href配置和资源路径拼接后再赋值给a标签,但这种方式在CDN缓存、服务端路径重写的场景下仍有概率失效,优先使用上面的方案,兼容所有静态托管环境。
内容的提问来源于stack exchange,提问作者jacob blankenship
相关产品推荐
相关产品推荐

