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 });
};
相关推荐
亿坊电商7 分钟前
VUE混合开发,选哪个PHP框架最顺手?
前端·vue.js·php
新人11yj415 分钟前
如何给网页增加滚动到顶部的功能
前端·javascript
掘金一周16 分钟前
Figma Dev Mode MCP:大人,时代变了 | 掘金一周7.10
前端·人工智能·mcp
Data_Adventure20 分钟前
推荐几款开源 Canvas 和 WebGL 图形库
前端·webgl·canvas
我爱加班、、34 分钟前
element-plus表单校验失败问题
前端·javascript·vue.js·elementui·ecmascript
香香甜甜的辣椒炒肉39 分钟前
vue快速上手
前端·javascript·vue.js
b1gbrother1 小时前
让你的Claude Code变得更聪明
前端·程序员
国家不保护废物1 小时前
多模态模型数据传输的秘密武器:html5对象Blob深度解析
前端·面试·html
用户2519162427111 小时前
Canvas之概述,画布与画笔
前端·javascript·canvas
南方kenny1 小时前
前端小知识:搞懂 BFC块级格式化上下文,告别面试“拦路虎”!
前端·css·面试