You need to enable JavaScript to run this app.
导航

断点续传拷贝(Browser.js SDK)

最近更新时间2024.02.04 18:31:06

首次发布时间2023.07.08 17:33:01

断点续传拷贝将待复制的对象分割为多个分段,并支持并发复制,待所有分段复制完成后,合并成完整的文件。

断点续传拷贝说明

断点续传拷贝适用于通过 TOS Browser SDK 在单个桶内或同区域的两个桶之间复制大对象的场景。TOS Browser SDK 提供了断点续传下载的功能,借助本地 CheckPoint 的机制记录已成功复制的分段,当出现网络异常或机器故障等问题导致分段复制中断,可再次调用该接口以实现续传的效果。您可以设置断点续传复制的分段大小、复制分段的并发数、事件回调函数等。同时也能在断点续传复制任务执行过程中,取消该任务。

注意事项

  • 为了避免在浏览器环境中暴露您的火山引擎账号密钥信息(即 AccessKey ID 和 AccessKey Secret),强烈建议您使用临时访问凭证的方式执行 TOS 相关操作,详细说明,请参见使用 STS 临时 AK/SK+Token 访问火山引擎 TOS
  • Endpoint 为 TOS 对外服务的访问域名。TOS 支持的 Endpoint 信息,请参见访问域名 Endpoint
  • 拷贝对象不支持跨区域的桶间拷贝。
  • 拷贝对象时,账号必须具备源对象的读取权限和目标桶的写入权限。
  • 拷贝对象时,可以保留所有元数据(默认值)或指定新的元数据。但 ACL 并未被保留,而是设置为私有。

示例代码

以下代码用于断点续传拷贝 srcBucket 桶中 srcObject 对象到 dstBucket桶中,并设置对象名为 dstObject 以及失败后重入下载。若复制过程中返回网络超时的报错,则以相同参数调用 resumableCopyObject 后实现断点续传下载重入。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>
  <body>
    <button id="upload">上传</button>
    <button id="copy">复制</button>
    <input id="file" type="file" />
    <!-- 导入 SDK 文件 -->
    <script src="https://tos-public.volccdn.com/obj/volc-tos-public/@volcengine/tos-sdk@latest/browser/tos.umd.production.min.js"></script>
    <script type="text/javascript">
      const client = new TOS({
        // yourRegion 填写Bucket 所在地域。以华北2(北京)为例,yourRegion 填写为 cn-beijing。
        region: yourRegion,
        // 填写 endpoint 名称。
        endpoint: yourEndpoint,
        // 从 STS 服务获取的临时访问密钥(AccessKey ID 和 AccessKey Secret)。
        accessKeyId: yourAccessKey,
        accessKeySecret: yourSecretKey,
        // 从 STS 服务获取的安全令牌(SecurityToken)。
        stsToken: yourSecurityToken,
        // 填写 Bucket 名称。
        bucket: examplebucket,
      });

      const srcBucket = yourSrcBucket; // 源桶
      const srcObject = 'exampledir/putResumableObject-test'; // 源对象
      const dstBucket = yourDstBucket; // 目标桶
      const dstObject = 'exampledir/resumableCopyObject-test'; // 目标对象
      const partSize = 5 * 1024 * 1024; // 分片大小

      // 上传文件
      const upload = document.getElementById('upload');
      upload.addEventListener('click', async () => {
        // 从输入框获取 file 对象,例如 <input type="file" id="file" />。
        const data = document.getElementById('file').files[0];
        try {
          await client.uploadFile({
            bucket: srcBucket,
            key: srcObject,
            file: data,
          });
        } catch (e) {
          console.log(e);
        }
      });

      // 生成 cancelTokenSource
      let cancelTokenSource = TOS.CancelToken.source();
      // 纪录断点
      let tosCheckpoint;

      const copy = document.getElementById('copy');
      copy.addEventListener('click', async () => {
        try {
          client.resumableCopyObject({
            bucket: dstBucket,
            key: dstObject,
            srcBucket,
            srcKey: srcObject,
            // 上传时指定分片大小
            partSize,
            // 注入 axios 的 cancelToken
            cancelToken: cancelTokenSource.token,
            progress: (percent, checkpoint) => {
              tosCheckpoint = checkpoint;
              console.log(percent, checkpoint);
            },
          });

          // 1 秒后取消任务
          setTimeout(() => {
            cancelTokenSource.cancel('manual cancel');
            console.log('cancel request');
          }, 1000);

          // 5 秒后继续上传
          setTimeout(() => {
            cancelTokenSource = TOS.CancelToken.source();
            client.resumableCopyObject({
              bucket: dstBucket,
              key: dstObject,
              srcBucket,
              srcKey: srcObject,
              // 上传时指定分片大小
              partSize,
              // 注入断点信息,继续上传
              checkpoint: tosCheckpoint,
              cancelToken: cancelTokenSource.token,
              progress: (percent, checkpoint) => {
                tosCheckpoint = checkpoint;
                console.log(percent, checkpoint);
              },
            });
          }, 5000);
        } catch (e) {
          console.log(e);
        }
      });
    </script>
  </body>
</html>