You need to enable JavaScript to run this app. 使用Fetch()实现文件下载时无法设置自定义文件名的问题咨询
优惠活动
大模型
产品
解决方案
定价
更多

使用Fetch()实现文件下载时无法设置自定义文件名的问题咨询

语法报错修复

你当前的报错是基础语法错误,第254行的解构参数缺少闭合右括号,正确写法如下:

.then( ({response, filename}) => {

文件名乱码/随机的根因与修复

先纠正两个误区

  • 客户端请求头加Content-Disposition完全无效,该字段是服务端返回的响应头,仅在响应阶段生效,你可以直接删掉客户端options里的这个头配置。
  • 直接调用window.location.assign跳转blob地址时,浏览器没有渠道获取自定义文件名,默认会把blob的UUID作为文件名,这是你拿到随机字符串文件名的核心原因。

修复步骤

  1. 服务端新增CORS暴露头配置
    你当前的服务端Content-Disposition响应头配置逻辑是正确的,但默认情况下前端JS无法读取自定义响应头,需要在express的响应逻辑里新增暴露头配置:
res
.set('Access-Control-Expose-Headers', 'Content-Disposition') // 新增这行,允许前端读取该响应头
.set('content-disposition', `attachment; filename="${filename}";  filename*=UTF-8''${encodeURI(filename)}`)
.type('.xlsx')
wb.write(filename, res);
  1. 适配无a标签调用的下载方案
    如果不能使用a标签点击的方案,优先适配现代浏览器支持的File System Access API,示例代码如下:
fetch("/api") // 删掉没用的请求头配置
  .then( res => {
    const filename = res.headers.get('Content-Disposition').split('filename=')[1].replace(/^"|"$/g, '');
    return {blob: res.blob(), filename}
  })
  .then( async ({blob, filename}) => {
    const fileBlob = await blob;
    const fileHandle = await window.showSaveFilePicker({
      suggestedName: filename,
      types: [{
        description: 'Excel文件',
        accept: {'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['.xlsx']}
      }]
    });
    const writable = await fileHandle.createWritable();
    await writable.write(fileBlob);
    await writable.close();
  });

如果需要兼容旧版浏览器,可引入FileSaver polyfill实现下载,可自行修改polyfill底层逻辑规避a标签调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 08:36:07