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時進行設置。