一、问题

在云存储项目中,由于使用 VFS 系统,文件 Blob 在物理硬盘(或对象存储)内的格式为 /objects/<uuid>
浏览器在下载时,默认提取 Path 最后一段作为文件名(即文件名为:<uuid>

二、解决方案

1. 若 CDN 支持动态改写响应 Header:

市面上其实大部分 CDN 都支持,但是部分厂商不会在控制台展示这个功能。
有的厂商需要提交工单配置(如:金山云 CDN);
有的厂商需要自行配置边缘函数规则(如:阿里云 ESA、腾讯云 EdgeOne)。
建议先看控制台有没有、再看是否支持边缘函数、最后提交工单询问、真搞不来也可以问问我(qq 2810132369)

在 CDN 响应头中动态新增 Header:

Content-Disposition: attachment; filename={动态插入请求URL中filename参数的值}
(如果你不需要访问 CDN 链接时强制下载,请将 attachment 改为 inline)
注:如果你的 CDN 源站为私有对象存储 Bucket,请务必在 CDN 配置:
当未命中缓存时,在回源时不携带 filename 参数。
如果不配置,那么回源会失败(报错:SignatureDoesNotMatch

2. 若 CDN 不支持动态改写响应 Header:

也是有办法的。

- 若你的前端域名和 CDN 域名同源:

(比如前端地址是https://user.edgecos.com,CDN 地址是https://user.edgecos.com/cdn,此时前端域名和 CDN 域名同源)

可利用 a 标签的 download 属性:

document.getElementById("downloadBtn").onclick = function () {
  const url = "";                           // 文件 CDN 地址
  const filename = "自定义文件名.pdf";       // 查询 VFS 数据表,得到的真实文件名
  const a = document.createElement("a");
  a.href = url;
  a.download = filename;
  a.style.display = "none";
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
};

(注意:这个方案的稳定性不太好,只能在前端域名和 CDN 域名同源时使用。并且并不是所有浏览器都支持该方案)

- 若你的服务器带宽比较大:

可以用服务器后端代理下载文件。但是这至少需要几百 Mbps 甚至数 Gbps 的公网上行带宽,并且会大量占用服务器资源。我想你应该不会愿意使用这个方案。

- 若你能接受下载文件的文件名固定为一个值:

可在 CDN 响应头添加静态 Header(所有 CDN 服务商一定都支持该功能)

Content-Disposition: attachment; filename=edgecos_download
(如果你不需要访问 CDN 链接时强制下载,请将 `attachment` 改为 `inline`)
你可以将 `edgecos_download` 改为你喜欢的文件名。

此方案使得所有下载的文件名不再是 <uuid>,而是 edgecos_download。不过,我认为你应该不会喜欢这个方案。能用就尽量用 二、1 的方案

最后修改:2026 年 07 月 22 日
如果觉得我的文章对你有用,请随意赞赏!