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 });
};
相关推荐
黄尚圈圈17 分钟前
Vue 中引入 ECharts 的详细步骤与示例
前端·vue.js·echarts
浮华似水1 小时前
简洁之道 - React Hook Form
前端
正小安3 小时前
如何在微信小程序中实现分包加载和预下载
前端·微信小程序·小程序
_.Switch5 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
一路向前的月光5 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   5 小时前
vite学习教程06、vite.config.js配置
前端·vite配置·端口设置·本地开发
长路 ㅤ   5 小时前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d
Fan_web5 小时前
jQuery——事件委托
开发语言·前端·javascript·css·jquery
安冬的码畜日常5 小时前
【CSS in Depth 2 精译_044】第七章 响应式设计概述
前端·css·css3·html5·响应式设计·响应式
莹雨潇潇6 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器