OSS 文件管理相关
公司使用了阿里云 OSS 云存储服务,前端在日常中会用到 浏览器端 的上传、下载等基础功能。
阿里云官网的 OSS 文档有些混乱,通常情况下,如果需要查询技术细节,官方的 Github JS SDK 代码库 中的介绍会更直观和详细,并且有丰富的单元测试用例做参考。
基础信息
OSS 有一些基础概念:
名词 | 含义 |
---|---|
bucket | 文件仓库,俗称 桶 |
region | bucket 所在区域,即传统服务器的机房所在地概念,如上海、香港 |
一个公司的 OSS 服务下,可以开通若干个处于不同 region
的 bucket
。
上传
一般情况下,出于安全考虑,在浏览器端进行 OSS 上传,会使用 STS Token 的方式进行鉴权,整体流程伪代码:
const uploadHandler = async (file: File) => {
// 1. 向后端提供的接口发起请求,申请签发临时的 sts-token 信息
const { data: stsTokenInfo } = await axios.post(YourStsTokenApi, {
fileType: 'ATTACHMENT' | 'EXCEL';
});
// 2. 使用临时 sts-token 信息,初始化 OSS Client
const {
bucket, region, accessKeyId, accessKeySecret, stsToken, path,
} = stsTokenInfo;
const client = new OSS({
secure: window.location.protocol === 'https:',
bucket,
region,
accessKeyId,
accessKeySecret,
stsToken,
});
// 3. 设置文件存放路径
const objectPath = `${path}/${file.name}`;
// 4. 执行上传任务
const result = await client.put(objectPath, file);
// 5. 对上传结果进行一些后续处理
// doSomething(result);
};
以前的实现,为了避免同名文件覆盖,后端在 STS Token 签发接口中内置了 "生成唯一文件名" 的功能,新的项目这部分交由前端自己去实现(objectPath 部分),比如上传时可以拼接时间戳。
OSS 的上传有 单个上传 PUT
和 分片上传 multipartUpload
两种方法,需要根据业务场景决定使用什么方法。
文件访问权限
OSS 的 bucket
创建时,需要设置读写权限。完整选项有三种:
- 私有
- 公共读
- 公共读写
实际开发中,前端和后端的沟通语境里简称为 公有 或 私有,即是否可以匿名访问。
- 公有
bucket
内的每个文件都自动生成外网可访问地址; - 私有
bucket
中的文件,必须通过后端接口 或 JS SDK(同样需要前置 STS Token) 临时签发文件访问地址,无法直接访问。
下载 和 预览
对于一个文件请求,浏览器会根据文件的 MIME 类型,去判断执行什么操作,比如访问图片、音频、视频地址,Chrome 会直接查看/播放;访问 zip 压缩包,则直接触发下载。
有些时候,产品会有同时提供 预览 和 下载 链接的需求。比如合同的 PDF 附件,会希望既可以直接预览,又可以点击就下载。
OSS 处理强制下载,只需要访问的时候,修改 header 即可,如
{
headers: {
'Content-Disposition': fileName
}
}
fileName
为你希望指定的保存文件名。
目前这一部分,交给后端生成 previewUrl
和 downloadUrl
,前端没有进行处理。
分片上传的一些细节
partSize
现在默认值即为 1024*1024 (1M)。另外,为防止网络超时问题,官网建议分片大小不小于 100K,不大于 1M
另外,源码中定义了文件的最小分片尺寸为 100K(100*1024),且 禁止 用户定义 的 partSize
小于 此默认值(会抛异常)。参见
parallel
同时可以上传的分片数,文档没有提及,源码中有定义 为 5
异常
之前遇到的:
abort
和cancel
是不同的函数- 按照官网示例,
abort
后判断err.name === 'abort
,但是实际抛出的err.name
为cancel
(2021 年 3 月 24 日)