-
Notifications
You must be signed in to change notification settings - Fork 566
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
166 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
var eachLimit = function (arr, limit, iterator, callback) { | ||
callback = callback || function () {}; | ||
if (!arr.length || limit <= 0) { | ||
return callback(); | ||
} | ||
|
||
var completed = 0; | ||
var started = 0; | ||
var running = 0; | ||
|
||
(function replenish () { | ||
if (completed >= arr.length) { | ||
return callback(); | ||
} | ||
|
||
while (running < limit && started < arr.length) { | ||
started += 1; | ||
running += 1; | ||
iterator(arr[started - 1], function (err) { | ||
|
||
if (err) { | ||
callback(err); | ||
callback = function () {}; | ||
} else { | ||
completed += 1; | ||
running -= 1; | ||
if (completed >= arr.length) { | ||
callback(); | ||
} else { | ||
replenish(); | ||
} | ||
} | ||
}); | ||
} | ||
})(); | ||
}; | ||
|
||
var Async = { | ||
eachLimit: eachLimit, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>自定义的分片上传</title> | ||
<style> | ||
h1, h2 { | ||
font-weight: normal; | ||
} | ||
|
||
#msg { | ||
margin-top: 10px; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
|
||
<h1>自定义的分片上传</h1> | ||
|
||
<input id="fileSelector" type="file"> | ||
<input id="submitBtn" type="submit"> | ||
|
||
<div id="msg"></div> | ||
|
||
<script src="../dist/cos-js-sdk-v5.js"></script> | ||
<script src="./common/async.js"></script> | ||
<script> | ||
(function () { | ||
// 请求用到的参数 | ||
var Bucket = 'test-1250000000'; | ||
var Region = 'ap-guangzhou'; | ||
var ChunkSize = 1024 * 1024 * 8; | ||
|
||
// 初始化 SDK | ||
var cos = new COS({ | ||
getAuthorization: function (options, callback) { | ||
var url = '/sts'; // 如果是 npm run sts.js 起的 nodejs server,使用这个 | ||
var xhr = new XMLHttpRequest(); | ||
xhr.open('GET', url, true); | ||
xhr.onload = function (e) { | ||
try { | ||
var data = JSON.parse(e.target.responseText); | ||
var credentials = data.credentials; | ||
} catch (e) { | ||
} | ||
if (!data || !credentials) return console.error('credentials invalid'); | ||
callback({ | ||
TmpSecretId: credentials.tmpSecretId, | ||
TmpSecretKey: credentials.tmpSecretKey, | ||
XCosSecurityToken: credentials.sessionToken, | ||
StartTime: data.startTime, // 时间戳,单位秒,如:1580000000,建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误 | ||
ExpiredTime: data.expiredTime, // 时间戳,单位秒,如:1580000900 | ||
}); | ||
}; | ||
xhr.send(); | ||
}, | ||
}); | ||
|
||
// 上传文件 | ||
var uploadFile = function (file, callback) { | ||
var fileSize = file.size; | ||
var Key = 'dir/' + file.name; // 这里指定上传目录和文件名 | ||
cos.multipartInit({ | ||
Bucket: Bucket, | ||
Region: Region, | ||
Key: Key, | ||
}, function (err, data) { | ||
if (err) return console.error('UploadId 创建出错:', err); | ||
var UploadId = data.UploadId; | ||
console.log('UploadId 已创建:', UploadId); | ||
var Parts = new Array(Math.ceil(fileSize / ChunkSize)).fill(0).map(function (item, index) { | ||
return {PartNumber: index + 1}; | ||
}); | ||
Async.eachLimit(Parts, 3, function (partItem, nextPart) { | ||
var PartNumber = partItem.PartNumber; | ||
var start = (PartNumber - 1) * ChunkSize; | ||
var end = Math.min(start + ChunkSize); | ||
var blob = file.slice(start, end); | ||
cos.multipartUpload({ | ||
Bucket: Bucket, | ||
Region: Region, | ||
Key: Key, | ||
UploadId: UploadId, | ||
PartNumber: PartNumber, | ||
Body: blob, | ||
}, function (err, data) { | ||
if (err) return nextPart(err); | ||
if (!data.headers.etag) return nextPart('浏览器获取不到 ETag Header,需要存储桶配置 CORS ExposeHeaders 允许当前域名跨域读取 ETag 字段。'); | ||
partItem.ETag = data.headers.etag || ''; | ||
console.log('分片上传完成:', partItem.PartNumber, partItem.ETag); | ||
nextPart(); | ||
}); | ||
}, function (err) { | ||
if (err) return console.error('上传分片出错:', err); | ||
cos.multipartComplete({ | ||
Bucket: Bucket, | ||
Region: Region, | ||
Key: Key, | ||
UploadId: UploadId, | ||
Parts: Parts, | ||
}, function (err, data) { | ||
if (err) return console.error('文件完成出错:', err); | ||
console.log('文件上传成功:', data.Location); | ||
callback(err, data); | ||
}); | ||
}); | ||
}); | ||
}; | ||
|
||
// 监听表单提交 | ||
document.getElementById('submitBtn').onclick = function (e) { | ||
var file = document.getElementById('fileSelector').files[0]; | ||
if (!file) { | ||
document.getElementById('msg').innerText = '未选择上传文件'; | ||
return; | ||
} | ||
file && uploadFile(file, function (err, data) { | ||
console.log(err || data); | ||
document.getElementById('msg').innerText = err ? err : ('上传成功,ETag=' + data.ETag); | ||
}); | ||
}; | ||
})(); | ||
</script> | ||
|
||
</body> | ||
</html> |