js实现ajax segment
使用原生JavaScript实现AJAX分段加载
XMLHttpRequest对象是原生JavaScript中实现AJAX的基础。以下展示如何通过XHR实现分段数据传输:
const xhr = new XMLHttpRequest();
xhr.open('GET', 'api/data', true);
xhr.setRequestHeader('Range', 'bytes=0-1023');
xhr.onprogress = function(event) {
if (event.lengthComputable) {
const percentComplete = (event.loaded / event.total) * 100;
console.log(`已加载: ${percentComplete.toFixed(2)}%`);
}
};
xhr.onload = function() {
if (xhr.status === 206) {
console.log('分段数据接收完成', xhr.response);
}
};
xhr.send();
Fetch API实现分段请求
现代浏览器支持的Fetch API提供了更简洁的异步请求方式:
fetch('api/large-file', {
headers: { 'Range': 'bytes=0-1023' }
})
.then(response => {
if (response.status === 206) {
return response.arrayBuffer();
}
throw new Error('分段请求失败');
})
.then(data => {
console.log('接收到数据片段', data);
});
处理分段数据合并
接收多个分段后需要合并数据的示例:

let receivedChunks = [];
let totalSize = 0;
function receiveChunk(chunk, startByte) {
receivedChunks.push({
data: chunk,
offset: startByte
});
totalSize += chunk.byteLength;
if (totalSize >= expectedTotalSize) {
assembleChunks();
}
}
function assembleChunks() {
receivedChunks.sort((a, b) => a.offset - b.offset);
const fullBuffer = new Uint8Array(totalSize);
let position = 0;
receivedChunks.forEach(chunk => {
fullBuffer.set(new Uint8Array(chunk.data), position);
position += chunk.data.byteLength;
});
console.log('完整数据已组装', fullBuffer);
}
服务器端配置要求
实现分段传输需要服务器支持以下功能:
- 正确解析
Range请求头 - 返回
206 Partial Content状态码 - 包含
Content-Range响应头 - 支持
multipart/byteranges内容类型
Node.js Express示例配置:

app.get('/large-file', (req, res) => {
const range = req.headers.range;
if (range) {
const [start, end] = range.replace(/bytes=/, '').split('-');
// 实现分段逻辑
res.writeHead(206, {
'Content-Range': `bytes ${start}-${end}/${fileSize}`,
'Accept-Ranges': 'bytes'
});
// 返回文件片段
}
});
进度监控与错误处理
完善的实现需要包含进度跟踪和错误恢复机制:
function loadSegment(url, start, end, retryCount = 0) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.setRequestHeader('Range', `bytes=${start}-${end}`);
xhr.onload = () => {
if (xhr.status === 206) {
resolve(xhr.response);
} else if (retryCount < 3) {
setTimeout(() => {
resolve(loadSegment(url, start, end, retryCount + 1));
}, 1000 * (retryCount + 1));
} else {
reject(new Error('Maximum retries exceeded'));
}
};
xhr.onerror = () => reject(new Error('Network error'));
xhr.send();
});
}
性能优化建议
针对大文件传输的优化方案:
- 使用Web Workers处理数据组装
- 实现并行分段下载
- 采用二进制格式传输(ArrayBuffer代替Base64)
- 添加本地缓存验证(If-Range头)
- 实现断点续传功能






