OSS提供的分片上传(MultipartUpload)功能,将要上传的较大文件(Object)分成多个分片(Part)来分别上传,上传完成后再调用CompleteMultipartUpload接口将这些Part组合成一个Object来达到断点续传的效果。

注意事项

  • 当您使用webpack或browserify等打包工具时,请通过npm install ali-oss的方式安装Browser.js SDK。
  • 由于Browser.js SDK通常在浏览器环境下使用,为避免暴露阿里云账号访问密钥(AccessKey ID和AccessKey Secret),强烈建议您使用临时访问凭证的方式执行OSS相关操作。

    搭建STS服务的具体操作请参见开发指南中的使用STS临时访问凭证访问OSS。您可以通过调用STS服务的AssumeRole接口或者使用各语言STS SDK来获取临时访问凭证。临时访问凭证包括临时访问密钥(AccessKey ID和AccessKey Secret)和安全令牌(SecurityToken)。

分片上传完整示例代码

当需要上传的文件大小较大时,您可以通过MultipartUpload接口进行分片上传。分片上传是指将要上传的文件分成多个数据块(Part)来分别上传。当其中一些分片上传失败后,OSS将保留上传进度记录,再次重传时只需要上传失败的分片,而不需要重新上传整个文件。

注意 通常在文件大于100 MB的情况下,建议采用分片上传的方法,通过断点续传和重试,提高上传成功率。如果在文件小于100 MB的情况下使用分片上传,且partSize设置不合理的情况下,可能会出现无法完整显示上传进度的情况。对于小于100 MB的文件,建议使用简单上传的方式。

以下代码以分片上传的方式将文件上传至examplebucket下的exampleobject.txt文件。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>

  <body>
    <button id="submit">上传</button>
    <input id="file" type="file" />
    <!-- 导入sdk文件 -->
    <script
      type="text/javascript"
      src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.16.0.min.js"
    ></script>
    <script type="text/javascript">
      const client = new OSS({
        // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
        region: "yourRegion",
        // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
        accessKeyId: "yourAccessKeyId",
        accessKeySecret: "yourAccessKeySecret",
        // 从STS服务获取的安全令牌(SecurityToken)。
        stsToken: "yourSecurityToken",
        // 填写Bucket名称,例如examplebucket。
        bucket: "examplebucket",
      });

      const headers = {
        // 指定该Object被下载时的网页缓存行为。
        "Cache-Control": "no-cache",
        // 指定该Object被下载时的名称。
        "Content-Disposition": "example.txt",
        // 指定该Object被下载时的内容编码格式。
        "Content-Encoding": "utf-8",
        // 指定过期时间,单位为毫秒。
        Expires: "1000",
        // 指定Object的存储类型。
        "x-oss-storage-class": "Standard",
        // 指定Object标签,可同时设置多个标签。
        "x-oss-tagging": "Tag1=1&Tag2=2",
        // 指定初始化分片上传时是否覆盖同名Object。此处设置为true,表示禁止覆盖同名Object。
        "x-oss-forbid-overwrite": "true",
      };

      // 指定上传到examplebucket的Object名称,例如exampleobject.txt。
      const name = "exampleobject.txt";
      // 获取DOM。
      const submit = document.getElementById("submit");
      const options = {
        // 获取分片上传进度、断点和返回值。
        progress: (p, cpt, res) => {
          console.log(p);
        },
        // 设置并发上传的分片数量。
        parallel: 4,
        // 设置分片大小。默认值为1 MB,最小值为100 KB。
        partSize: 1024 * 1024,
        // headers,
        // 自定义元数据,通过HeadObject接口可以获取Object的元数据。
        meta: { year: 2020, people: "test" },
        mime: "text/plain",
      };

      // 监听按钮。
      submit.addEventListener("click", async () => {
        try {
          const data = document.getElementById("file").files[0];
          // 分片上传。
          const res = await client.multipartUpload(name, data, {
            ...options,
            // 设置上传回调。
            // 如果不涉及回调服务器,请删除callback相关设置。
            callback: {
              // 设置回调请求的服务器地址。
              url: "http://examplebucket.aliyuncs.com:23450",
              // 设置回调请求消息头中Host的值,即您的服务器配置Host的值。
              host: "yourHost",
              /* eslint no-template-curly-in-string: [0] */
              // 设置发起回调时请求body的值。
              body: "bucket=${bucket}&object=${object}&var1=${x:var1}",
              // 设置发起回调请求的Content-Type。
              contentType: "application/x-www-form-urlencoded",
              customValue: {
                // 设置发起回调请求的自定义参数。
                var1: "value1",
                var2: "value2",
              },
            },
          });
          console.log(res)
        } catch (err) {
          console.log(err);
        }
      });
    </script>
  </body>
</html>

在使用MultipartUpload接口时,如果遇到ConnectionTimeoutError超时问题,业务方需自行处理超时逻辑。例如通过缩小分片大小、增加超时时间、重试请求或者捕获ConnectionTimeoutError错误等方法处理超时。更多信息,请参见网络错误处理

取消分片上传事件

您可以调用client.abortMultipartUpload方法来取消分片上传事件。当一个分片上传事件被取消后,无法再使用该uploadId进行任何操作,已上传的分片数据会被删除。

以下代码用于取消分片上传事件:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <title>Document</title>
</head>

<body>
  <button id='submit'>上传</button>
  <button id='abort'>中断</button>
     <!-- 导入sdk文件 -->
  <script type="text/javascript" src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.16.0.min.js"></script>
  <script type="text/javascript">
    const client = new OSS({
       // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
       region: 'yourRegion',
       // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
       accessKeyId: 'yourAccessKeyId',
       accessKeySecret: 'yourAccessKeySecret',
       // 从STS服务获取的安全令牌(SecurityToken)。
       stsToken: 'yourSecurityToken',
       // 填写Bucket名称,例如examplebucket。
       bucket: "examplebucket",
      });
    // 生成用于分片上传的100 MB大小的文件。  
    const fileContent = Array(1024 * 1024 * 100).fill('a').join('')
    const file = new File([fileContent], 'multipart-upload-file')
    // 设置上传到examplebucket的Object名称,例如exampleobject.txt。
    const name = "exampleobject.txt";
    // 设置中断点。
    let abortCheckpoint
    // 获取DOM。
    const submit = document.getElementById('submit');
    const abort = document.getElementById('abort')

    // 监听上传按钮,单击“上传”后开始分片上传。
    submit.addEventListener('click', async () => {
      try {
        const res = await client.multipartUpload(name, file, {
          progress: (p, cpt, res) => {
            // 为中断点赋值。
            abortCheckpoint = cpt
            // 获取上传进度。
            console.log(p)
          }
        })
      } catch (err) {
        console.log(err)
      }
    })
    // 监听中断按钮。
    abort.addEventListener('click', () => {
    // 中断分片上传。
    client.abortMultipartUpload(abortCheckpoint.name, abortCheckpoint.uploadId)
    })
  </script>
</body>

</html>

列举已上传的分片

调用client.listParts方法列举出指定uploadId下所有已经上传成功的分片。

以下代码用于列举已上传的分片:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <title>Document</title>
</head>

<body>
  <button id='check'>列举已上传的分片</button>
  <!-- 导入sdk文件 -->
  <script type="text/javascript" src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.16.0.min.js"></script>
  <script type="text/javascript">
    const client = new OSS({
       // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
       region: 'yourRegion',
       // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
       accessKeyId: 'yourAccessKeyId',
       accessKeySecret: 'yourAccessKeySecret',
       // 从STS服务获取的安全令牌(SecurityToken)。
       stsToken: 'yourSecurityToken',
       // 填写Bucket名称,例如examplebucket。
       bucket: "examplebucket",
      });
    // 生成用于分片上传的100 MB大小的文件。    
    const fileContent = Array(1024 * 1024 * 100).fill('a').join('')
    const file = new File([fileContent], 'multipart-upload-file')
    // 设置上传到examplebucket的Object名称,例如exampleobject.txt。
    const name = "exampleobject.txt";
    // 设置中断点。
    let abortCheckpoint

    // 获取DOM。
    const submit = document.getElementById('submit');
    const check = document.getElementById('check')

    // 监听按钮。
    submit.addEventListener('click', async () => {
      try {
        const res = await client.multipartUpload(name, file, {
          progress: (p, cpt, res) => {
            // 为中断点赋值。
            abortCheckpoint = cpt
            // 获取上传进度。
            console.log('progress=====', p)
          }
        })
      } catch (err) {
        console.log(err)
      }
    })
      // 监听按钮。
      check.addEventListener('click', async () => {
      // 列举已上传的分片.
      const result = await client.listParts(name, abortCheckpoint.uploadId)
      console.log(result)
    })
  </script>
</body>

</html>

列举分片上传事件

调用client.listUploads方法列举出所有执行中的分片上传事件,即已初始化但尚未完成或已取消的分片上传事件。

以下代码用于列举分片上传事件:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <title>Document</title>
</head>

<body>
  <button id='check'>列举分片上传事件</button>
  <!-- 导入sdk文件 -->
  <script type="text/javascript" src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.16.0.min.js"></script>
  <script type="text/javascript">
      const client = new OSS({
         // yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
         region: 'yourRegion',
         // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
         accessKeyId: 'yourAccessKeyId',
         accessKeySecret: 'yourAccessKeySecret',
         // 从STS服务获取的安全令牌(SecurityToken)。
        stsToken: 'yourSecurityToken',
        // 填写Bucket名称,例如examplebucket。
        bucket: "examplebucket",
    });

    // 获取DOM。
    const check = document.getElementById('check')

    // 监听按钮。
    check.addEventListener('click', async () => {
      // 获取所有已初始化但尚未完成或已取消的分片上传事件。
      const result = await client.listUploads({ 'max-uploads': 100 })
      console.log('uploads', result.uploads)
    })
  </script>
</body>

</html>

相关文档

  • 关于分片上传的完整示例代码,请参见GitHub示例
  • Browser.js SDK分片上传调用的方法multipartUpload中封装了三个API接口,详情如下:
  • 关于取消分片上传事件的API接口说明,请参见AbortMultipartUpload
  • 关于列举已上传分片的API接口说明,请参见ListParts
  • 关于列举所有执行中的分片上传事件(即已初始化但尚未完成或已取消的分片上传事件)的API接口说明,请参见ListMultipartUploads