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

Flutter Web本地文件下载正常 生产环境提示无文件如何解决

问题现象

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

原有实现代码:

  • 下载函数
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地址触发下载,完全不受部署路径、托管服务路由规则影响:

  1. 在对应组件文件头部引入需要的依赖
import 'dart:html';
import 'package:flutter/services.dart';
  1. 把原有按钮的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 18:54:23