AWS S3 、阿里OSS的文件如何重命名?

目前JS下载文件的方式有两种:

js 复制代码
// 第一种,直接a标签下载,download修改文件名不会生效,浏览器会有下载文件的交互,大文件体验好
  const a = document.createElement('a');
  a.href = downloadUrl;
  a.download = "new_filename.txt"; // 设置文件名
  a.click();
  a.remove();
 
 
// 第二种,需要等blob下载完之后才能改名,大文件需要等待,体验差
  const result = await axios(path, {
    method: 'get',
    responseType: 'blob',
  });
  const blob = new Blob([result.data]);
  const a = document.createElement('a');
  a.download = "new_filename.txt"; // 设置文件名
  a.href = URL.createObjectURL(blob);
  a.click();
  URL.revokeObjectURL(a.href);
  a.remove();

为了更好的用户体验,我们肯定是要选择第一种,那有什么办法可以既保持用户体验的同时又可以修改文件名呢。

下面先介绍一个HTTP Response Header

1. Content-Disposition

Content-Disposition 是 HTTP 头部中的一个字段,它指示了如何处理响应的内容。这个头部字段通常用于告诉浏览器如何处理服务器发送的文件下载,特别是如何处理文件的文件名和下载行为。

它的值可以有几种不同的形式:

  1. inline:指示浏览器直接在页面上显示响应的内容,而不是将其下载到本地计算机。
  2. attachment:指示浏览器应该将响应的内容作为附件下载到本地计算机。
  3. filename=filename.ext:指示下载的文件名为 filename.ext。浏览器将使用这个文件名来保存下载的文件。如果这个参数不存在,那么浏览器通常会使用最后一个斜杠后的部分作为文件名。

例如,一个典型的 Content-Disposition 头部可能是这样的:

css 复制代码
Content-Disposition: attachment; filename="example.txt"

这个头部告诉浏览器应该将响应的内容作为附件下载,并且文件名应该为 "example.txt"。

如果我们可以修改AWS S3 、阿里OSS的对象存储URL Response headers 中的 Content-Disposition,那么我们可以采用第一种下载的方式,并且重命名资源了。

2. 具体实现

那么查找文档可以发现,AWS S3 和 阿里 OSS 都支持通过签名的方式修改Content-Disposition。

AWS S3:

ts 复制代码
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner"

export const downloadAWSFile = async (path: string, filename: string) => {
  const client = new S3Client({
    region: S3_REGION, // 区域
    credentials: {}, // 验证信息
  });
  const { GetObjectCommand } = await import('@aws-sdk/client-s3');
  const command = new GetObjectCommand({
    Bucket,
    Key,
    ResponseContentDisposition: `attachment; filename=${filename}`,
  });
  return getSignedUrl(client, command);
};

阿里 OSS:

ts 复制代码
import OSS from "ali-oss";

export const downloadOSSFile = async (path: string, filename: string) => {
  const client = new OSS({
    accessKeyId,
    accessKeySecret,
    bucket,
    region,
  });
  const { Key } = getOSSInfoFromUrl(path);
  const response = {
    'content-disposition': `attachment; filename=${encodeURIComponent(filename)}`,
  };
  return client.signatureUrl(Key, { response });
};
相关推荐
友友马9 小时前
『 QT 』QT控件属性全解析 (一)
开发语言·前端·qt
不想上班只想要钱10 小时前
vue3+vite创建的项目,运行后没有 Network地址
前端·javascript·vue.js
流***陌10 小时前
手办盲盒抽赏小程序前端功能设计:兼顾收藏需求与抽赏乐趣
前端·小程序
岁月宁静11 小时前
在富文本编辑器中封装实用的 AI 写作助手功能
前端·vue.js·人工智能
金士顿11 小时前
为什么MainWindow.xaml绑定的datacontext,EtherCATSuiteCtrl.xaml直接用了?
前端
533_11 小时前
[css] flex布局中的英文字母不换行问题
前端·css
浮游本尊11 小时前
React 18.x 学习计划 - 第四天:React Hooks深入
前端·学习·react.js
future_studio11 小时前
聊聊 Unity(小白专享、C# 小程序 之 日历、小闹钟)
前端·html
Yeats_Liao12 小时前
Go Web 编程快速入门 · 04 - 请求对象 Request:头、体与查询参数
前端·golang·iphone
祈祷苍天赐我java之术12 小时前
Redis 数据类型与使用场景
java·开发语言·前端·redis·分布式·spring·bootstrap