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

React中使用AWS S3预签名URL实现文件本地下载的问题

解决React中AWS S3预签名URL无法触发本地下载的问题

你的代码核心问题是把预签名URL字符串塞进了Blob对象,这相当于创建了一个仅包含URL文本内容的文件,而非指向S3实际文件的有效链接,所以浏览器会打开这个文本内容,而非触发下载。下面是两种可行的修复方案:

方案一:直接使用预签名URL(推荐)

预签名URL本身就是可直接访问的文件链接,只要配置正确,配合download属性就能触发下载:

downloadFile(payload).then((res) => {
  const link = document.createElement('a');
  link.href = res.url; // 直接使用预签名URL
  link.setAttribute('download', res.fileName);
  // 部分浏览器需要设置target="_blank"确保下载触发
  link.target = '_blank';
  
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
});

关键注意点

如果这样仍打开新页面预览文件,说明S3返回的响应头缺少Content-Disposition配置。生成预签名URL时,需要添加该参数(以AWS SDK v3为例):

// 生成预签名URL的代码示例
const command = new GetObjectCommand({
  Bucket: 'your-bucket-name',
  Key: 'your-file-key',
  ContentDisposition: `attachment; filename="${fileName}"` // 强制浏览器触发下载
});
const signedUrl = await getSignedUrl(s3Client, command, { expiresIn: 3600 });

方案二:通过Fetch获取Blob后下载(适合需处理文件内容的场景)

如果需要先获取文件内容再下载(比如修改内容),可以用Fetch请求预签名URL,拿到真实的文件Blob:

downloadFile(payload).then((res) => {
  fetch(res.url)
    .then(response => {
      if (!response.ok) throw new Error('文件下载失败');
      return response.blob();
    })
    .then(blob => {
      const url = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.setAttribute('download', res.fileName);
      
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      // 释放URL对象,避免内存泄漏
      URL.revokeObjectURL(url);
    })
    .catch(err => console.error(err));
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 06:42:39