Skip to content

OSS 文件管理相关

公司使用了阿里云 OSS 云存储服务,前端在日常中会用到 浏览器端 的上传、下载等基础功能。

阿里云官网的 OSS 文档有些混乱,通常情况下,如果需要查询技术细节,官方的 Github JS SDK 代码库 中的介绍会更直观和详细,并且有丰富的单元测试用例做参考。

基础信息

OSS 有一些基础概念:

名词含义
bucket文件仓库,俗称
regionbucket 所在区域,即传统服务器的机房所在地概念,如上海、香港

一个公司的 OSS 服务下,可以开通若干个处于不同 regionbucket

上传

一般情况下,出于安全考虑,在浏览器端进行 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 为你希望指定的保存文件名。

目前这一部分,交给后端生成 previewUrldownloadUrl,前端没有进行处理。

分片上传的一些细节

partSize

现在默认值即为 1024*1024 (1M)。另外,为防止网络超时问题,官网建议分片大小不小于 100K,不大于 1M

另外,源码中定义了文件的最小分片尺寸为 100K(100*1024),且 禁止 用户定义 的 partSize 小于 此默认值(会抛异常)。参见

parallel

同时可以上传的分片数,文档没有提及,源码中有定义 为 5

异常

之前遇到的:

  1. abortcancel 是不同的函数
  2. 按照官网示例, abort 后判断 err.name === 'abort,但是实际抛出的 err.namecancel (2021 年 3 月 24 日)