全部產品
Search
文件中心

Object Storage Service:Browser.js分區上傳

更新時間:Nov 13, 2024

OSS提供的分區上傳(MultipartUpload)功能,將要上傳的較大檔案(Object)分成多個分區(Part)來分別上傳,上傳完成後再調用CompleteMultipartUpload介面將這些Part組合成一個Object來達到斷點續傳的效果。

注意事項

  • 在分區上傳之前,請確保您已瞭解該功能。更多資訊,請參見分區上傳

  • 當您使用webpack或browserify等打包工具時,請通過npm install ali-oss的方式安裝Browser.js SDK。

  • 通過瀏覽器訪問OSS時涉及跨域請求,如果未設定跨域規則,瀏覽器會拒絕跨域訪問請求。如果您希望通過瀏覽器可以正常訪問OSS,需要通過OSS設定跨域規則。具體操作,請參見準備工作

  • 由於Browser.js SDK通常在瀏覽器環境下使用,為避免暴露阿里雲帳號存取金鑰(AccessKey ID和AccessKey Secret),強烈建議您使用臨時訪問憑證的方式執行OSS相關操作。

    臨時訪問憑證包括臨時存取金鑰(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.18.0.min.js"
    ></script>
    <script type="text/javascript">
      const client = new OSS({
        // yourRegion填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為oss-cn-hangzhou。
        region: "yourRegion",
        authorizationV4: true,
        // 從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.18.0.min.js"
    ></script>
    <script type="text/javascript">
      const client = new OSS({
        // yourRegion填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為oss-cn-hangzhou。
        region: "yourRegion",
        authorizationV4: true,
        // 從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="submit">上傳</button>
    <button id="check">列舉已上傳的分區</button>
    <!--匯入sdk檔案-->
    <script
      type="text/javascript"
      src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.18.0.min.js"
    ></script>
    <script type="text/javascript">
      const client = new OSS({
         // yourRegion填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為oss-cn-hangzhou。
         region: 'yourRegion',
         authorizationV4: true,
         // 從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.18.0.min.js"
    ></script>
    <script type="text/javascript">
      const client = new OSS({
         // yourRegion填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為oss-cn-hangzhou。
         region: 'yourRegion',
         authorizationV4: true,
         // 從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

常見問題

報錯PLease set the etag of expose-headers in Oss.如何處理?

  • 問題原因

    未正確設定跨域。

  • 解決方案

    您需要為當前Bucket設定跨域。設定跨域規則時需要暴露常見Header(x-oss-request-idETag)。具體步驟,請參見跨網域設定

報錯The operation is not supported for this resource.如何處理?

  • 問題原因

    您在調用CompleteMultipartUpload介面時設定了Object儲存類型。

  • 解決方案

    不支援在分區上傳過程中調用CompleteMultipartUpload時設定Object儲存類型。如果您需要在分區上傳過程中指定Object儲存類型,您需要在調用InitiateMultipartUpload時進行設定。