You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌入式系统POST文件上传在Safari中进度直接跳100%求助

Safari下XHR文件上传进度直接跳100%的排查与解决

针对嵌入式Web服务器文件上传功能在Safari中进度直接跳至100%的问题,结合你的代码和Safari特性,给出以下排查思路与解决方案:

1. 先校验进度事件的可计算状态

Safari在上传初期可能无法正确获取文件总大小(event.total),导致event.loaded/event.total直接算出100%的结果。必须先判断进度是否可计算,再更新UI:

修改你的progress事件处理逻辑:

request.upload.addEventListener('progress', event => {
    // 先判断是否能计算有效进度
    if (!event.lengthComputable) {
        uploadForm.querySelector('.result').innerHTML = '<div>Uploading...</div>';
        return;
    }
    var progressPc = Math.round((event.loaded/event.total)*100);
    console.log(`event loaded ${event.loaded} of total ${event.total}`);
    uploadForm.querySelector('.result').innerHTML = `<div>Uploading... (${progressPc}%)</div>`;
    uploadForm.querySelector('.progress').style.display = "block";
    uploadForm.querySelector('.progress').style.background = `linear-gradient(to right, #25b3FF, #870404 ${progressPc}%, #e6e8ec ${progressPc}%)`;
});

2. 检查服务器端传输配置

嵌入式服务器的以下设置可能导致Safari一次性触发进度:

  • 未启用分块传输编码(Transfer-Encoding: chunked):Safari会先缓存整个文件再发送,直接触发100%进度。需确保服务器支持分块传输,或在响应头中正确返回Content-Length。
  • 服务器接收逻辑:如果服务器要等整个文件接收完成才返回响应,Safari可能不会触发中间的progress事件。可调整服务器在接收文件块时及时ACK客户端的发送请求。

3. 补充监听其他上传事件,完善状态提示

Safari的progress事件可能在文件发送完成后才一次性触发,但此时服务器可能还在处理文件。建议补充监听相关事件,避免误判进度:

// 上传开始
request.upload.addEventListener('loadstart', () => {
    uploadForm.querySelector('.result').innerHTML = '<div>Starting upload...</div>';
    uploadForm.querySelector('.progress').style.display = "block";
    uploadForm.querySelector('.progress').style.background = `linear-gradient(to right, #25b3FF, #870404 0%, #e6e8ec 0%)`;
});

// 客户端发送完毕(等待服务器处理)
request.upload.addEventListener('load', () => {
    uploadForm.querySelector('.result').innerHTML = '<div>Upload sent, waiting for server response...</div>';
});

// 服务器返回响应(上传流程完成)
request.addEventListener('load', () => {
    uploadForm.querySelector('.result').innerHTML = '<div>Upload completed!</div>';
});

4. 修复变量作用域问题

代码中uploadFormData和request未用let/const声明,属于全局变量,多次上传可能引发冲突。建议改为局部变量:

const uploadFormData = new FormData(uploadForm);
const request = new XMLHttpRequest();

内容的提问来源于stack exchange,提问作者Josh Bennett

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 14:31:04