js实现文件上传限速
实现文件上传限速的方法
在JavaScript中实现文件上传限速可以通过控制上传数据的速率来实现。以下是几种常见的方法:

使用XMLHttpRequest和定时器
通过XMLHttpRequest对象发送文件数据,结合定时器控制上传速率。

function uploadWithThrottle(file, url, maxSpeed) {
const chunkSize = maxSpeed * 1024; // 转换为KB
const totalChunks = Math.ceil(file.size / chunkSize);
let currentChunk = 0;
function uploadNextChunk() {
const start = currentChunk * chunkSize;
const end = Math.min(start + chunkSize, file.size);
const chunk = file.slice(start, end);
const xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/octet-stream');
xhr.setRequestHeader('X-Chunk-Number', currentChunk);
xhr.setRequestHeader('X-Total-Chunks', totalChunks);
xhr.onload = function() {
if (currentChunk < totalChunks - 1) {
currentChunk++;
setTimeout(uploadNextChunk, 1000); // 延迟1秒上传下一块
}
};
xhr.send(chunk);
}
uploadNextChunk();
}
使用Fetch API和AbortController
利用Fetch API和AbortController实现更精细的速率控制。
async function throttledUpload(file, url, maxSpeed) {
const chunkSize = maxSpeed * 1024;
const totalChunks = Math.ceil(file.size / chunkSize);
const controller = new AbortController();
for (let i = 0; i < totalChunks; i++) {
const start = i * chunkSize;
const end = Math.min(start + chunkSize, file.size);
const chunk = file.slice(start, end);
try {
await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/octet-stream',
'X-Chunk-Number': i,
'X-Total-Chunks': totalChunks
},
body: chunk,
signal: controller.signal
});
await new Promise(resolve => setTimeout(resolve, 1000));
} catch (error) {
if (error.name === 'AbortError') {
console.log('Upload aborted');
} else {
console.error('Upload error:', error);
}
break;
}
}
}
使用WebSocket实现实时控制
WebSocket可以提供更实时的上传速率控制。
function wsUpload(file, wsUrl, maxSpeed) {
const ws = new WebSocket(wsUrl);
const chunkSize = maxSpeed * 1024;
const totalChunks = Math.ceil(file.size / chunkSize);
let currentChunk = 0;
ws.onopen = function() {
sendNextChunk();
};
function sendNextChunk() {
if (currentChunk >= totalChunks || ws.readyState !== WebSocket.OPEN) return;
const start = currentChunk * chunkSize;
const end = Math.min(start + chunkSize, file.size);
const chunk = file.slice(start, end);
const reader = new FileReader();
reader.onload = function(e) {
ws.send(e.target.result);
currentChunk++;
if (currentChunk < totalChunks) {
setTimeout(sendNextChunk, 1000);
}
};
reader.readAsArrayBuffer(chunk);
}
}
注意事项
- 速率单位应统一为KB/s或MB/s
- 服务器端需要支持分块上传
- 需要考虑网络延迟和重试机制
- 大文件上传需要实现断点续传功能
以上方法可以根据实际需求进行调整,结合进度条显示等用户体验优化措施。






