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介面說明,請參見InitiateMultipartUpload。
關於分區上傳Part的API介面說明,請參見UploadPart。
關於完成分區上傳的API介面說明,請參見CompleteMultipartUpload。
關於取消分區上傳事件的API介面說明,請參見AbortMultipartUpload。
關於列舉已上傳分區的API介面說明,請參見ListParts。
關於列舉所有執行中的分區上傳事件(即已初始化但尚未完成或已取消的分區上傳事件)的API介面說明,請參見ListMultipartUploads。
常見問題
報錯PLease set the etag of expose-headers in Oss.如何處理?
問題原因
未正確設定跨域。
解決方案
您需要為當前Bucket設定跨域。設定跨域規則時需要暴露常見Header(x-oss-request-id和ETag)。具體步驟,請參見跨網域設定。
報錯The operation is not supported for this resource.如何處理?
問題原因
您在調用CompleteMultipartUpload介面時設定了Object儲存類型。
解決方案
不支援在分區上傳過程中調用CompleteMultipartUpload時設定Object儲存類型。如果您需要在分區上傳過程中指定Object儲存類型,您需要在調用InitiateMultipartUpload時進行設定。