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

目前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 头部可能是这样的:

Content-Disposition: attachment; filename="example.txt"

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

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

2. 具体实现

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

AWS S3:

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:

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 });
};

原文链接:https://juejin.cn/post/7356055901495328777 作者:yasuomang

(0)
上一篇 2024年4月11日 上午10:21
下一篇 2024年4月11日 上午10:31

相关推荐

发表回复

登录后才能评论