Documentation: https://help.aliyun.com/document_detail/383953.html?spm=a2c4g.383947.0.0.47607d9dnkBjdG
Code Implementation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Document</title>
</head>
<body>
<input type="file" id="file">
<span id="process"></span>
<button id="submit">Resume Upload</button>
<!-- Import SDK -->
<script
type="text/javascript"
src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.16.0.min.js"
></script>
<script type="text/javascript">
// Use multiple clients for multi-file uploads
const client = new OSS({
// Replace yourRegion with actual region code
region: 'yourRegion',
// Get from STS service
accessKeyId: 'yourAccessKeyId',
accessKeySecret: 'yourAccessKeySecret',
stsToken: 'yourSecurityToken',
bucket: "examplebucket",
});
// Define checkpoint for resume
let abortCheckpoint;
// Get DOM elements
let uploadFile;
const process = document.getElementById("process");
const file = document.getElementById("file");
const submit = document.getElementById("submit");
// File selection handler
file.addEventListener('change', function () {
uploadFile = this.files[0];
// Generate unique ID (recommend using MD5 hash)
uploadFile.id = '' + uploadFile.size + uploadFile.name;
uploadFile.checkpoint = getData(uploadFile);
// Display progress
if (uploadFile.checkpoint) {
process.innerText = uploadFile.checkpoint.process + '%';
} else {
process.innerText = 'No resume data';
}
});
// Upload button handler
submit.addEventListener("click", function () {
if (!uploadFile) {
alert('No file selected');
return;
}
let filename = uploadFile.id;
let checkpointData = uploadFile.checkpoint;
// Handle existing checkpoint
if (checkpointData) {
if (checkpointData.process === 100) {
// Upload completed, submit to backend
// deleteData(uploadFile);
return;
}
checkpointData.file = uploadFile;
}
// Initiate multipart upload
client
.multipartUpload(filename, uploadFile, {
progress: (p, checkpoint, res) => {
let processVal = Math.round(p * 100);
process.innerText = processVal + ' %';
// Update progress
checkpoint.process = processVal;
setData(uploadFile, checkpoint);
},
// 100KB chunks for demo
partSize: 1024 * 100,
checkpoint: checkpointData,
})
.then(function (r) {
console.log(r);
// Cleanup after completion
deleteData(uploadFile);
});
});
// Local storage helpers
function getData(file) {
let data = JSON.parse(window.localStorage.getItem(file.id));
return data ? data : null;
}
function setData(file, checkpoint) {
const storageData = {
file: null,
name: checkpoint.name,
fileSize: checkpoint.fileSize,
partSize: checkpoint.partSize,
uploadId: checkpoint.uploadId,
doneParts: checkpoint.doneParts,
process: checkpoint.process
};
window.localStorage.setItem(file.id, JSON.stringify(storageData));
}
function deleteData(file) {
window.localStorage.removeItem(file.id);
}
</script>
</body>
</html>
Key Features
- Resumable Uploads: Stores upload progress in localStorage
- Progress Tracking: Real-time percentage display
- Chunk Upload: 100KB chunks for better reliability
- Checkpoint Management: Automatic resume from last successful chunk
Implementation Notes
- Uses browser’s localStorage for checkpoint persistence
- Requires valid OSS credentials (AccessKey/STS Token)
- File identification uses size+name combination (MD5 recommended for production)
- Cleanup completed uploads automatically