移动端XML上传易因网络切换失败,因TCP连接重置导致请求中断且无断点续传;需用Blob分片、uploadId、本地存储及服务端校验实现可恢复上传。
移动端上传XML时为什么容易因网络切换失败
因为移动设备在Wi-Fi和蜂窝网络间切换时,TCP连接大概率会重置,XMLHttpRequest 或 fetch 会直接抛出 NetworkError 或进入 aborted 状态,而原生上传不带断点续传能力,整个 XML 文件得从头重发。
用 Blob 分片 + 唯一请求ID实现可恢复上传
核心是把大 XML 拆成固定大小的 Blob 片段(比如 512KB),每片单独上传,并附带当前分片序号、总片数、文件哈希和客户端生成的 uploadId。服务端按 uploadId 聚合所有成功接收的分片,最后拼接并校验完整 XML。
-
前端需监听
navigator.onLine变化,在离线时暂停上传队列,切回在线后自动重试未完成分片 - 每个分片请求必须设
timeout(建议 15–30s),避免卡死在弱网中 - 使用
AbortController控制单个分片请求生命周期,网络切换时主动abort()并标记该片待重试 - XML 内容若含敏感字段,应在分片前用
TextEncoder转为Uint8Array,再加密(如 AES-GCM)——服务端解密后才拼接,避免中间态明文泄露
const uploadChunk = async (blob, index, total, uploadId, signal) => {
const formData = new FormData();
formData.append('chunk', blob);
formData.append('index', index);
formData.append('total', total);
formData.append('uploadId', uploadId);
const res = await fetch('/api/upload-xml-chunk', {
method: 'POST',
body: formData,
signal
});
if (!res.ok) throw new Error(`Chunk ${index} failed: ${res.status}`);
return res.json();
};
服务端必须校验分片完整性与顺序
仅靠前端传的 index 不可靠——可能乱序到达或重复提交。服务端要:对每个 uploadId 维护一个 Redis Hash,键为 upload:${uploadId}:chunks,字段是 index,值为该分片 SHA-256;收到新分片时先比对哈希,一致才写入;合并前检查是否收齐 0..total-1 且无缺失。