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

AJAX多文件单独上传:实现顺序上传、进度条及表单提交控制

多文件串行上传(带进度跟踪)解决方案

问题现状

当前代码会同时发起所有文件的上传请求,导致进度条无法准确对应单个文件的上传状态,且无法判断全部上传完成的时机来提交表单。需要修改为串行上传(完成一个再传下一个),并在全部上传完成后触发表单提交。

修改后的代码

HTML(新增进度条与状态提示)

<div id="dropzone-zone">
    <button type="submit" class="btn btn-primary btn-xs" id="add_file" name="add_file" form="upload-form" style="display:none;">Subir archivos</button>
    <form action="" id="upload-form" method="post" enctype="multipart/form-data">
        <div id="dropzone" class="drop-zone" style="display:block;">
            <span class="drop-zone__prompt">Haga click o arrastre los archivos que desea subir.</span>
            <input type="file" name="file-upload[]" style="display:none;" id="file-upload" class="drop-zone__input" multiple>
            <!-- 单个文件上传进度条 -->
            <progress id="load-progress" value="0" max="100" style="width:100%;margin-top:10px;"></progress>
            <!-- 上传状态提示 -->
            <div id="upload-status" style="margin-top:8px;color:#666;"></div>
        </div>
    </form>
</div>

JavaScript(改为串行上传+完成判断)

const inputElement = document.getElementById("file-upload");
const dropZoneElement = document.getElementById("dropzone");
const progressBar = document.getElementById("load-progress");
const statusText = document.getElementById("upload-status");
const submitBtn = document.getElementById("add_file");

dropZoneElement.addEventListener("dragover", (e) => { e.preventDefault(); });

dropZoneElement.addEventListener("drop", (e) => {
    e.preventDefault();
    inputElement.files = e.dataTransfer.files;
    dropZoneElement.querySelector(".drop-zone__prompt").remove();

    // 将文件列表转为数组,方便顺序处理
    const filesArray = Array.from(inputElement.files);
    let currentFileIndex = 0;

    // 递归处理单个文件上传
    function uploadNextFile() {
        if (currentFileIndex >= filesArray.length) {
            // 所有文件上传完成,提交表单
            statusText.textContent = "Todos los archivos se subieron correctamente, enviando formulario...";
            submitBtn.click();
            return;
        }

        const currentFile = filesArray[currentFileIndex];
        statusText.textContent = `Subiendo: ${currentFile.name} (${currentFileIndex + 1}/${filesArray.length})`;
        
        const formdata = new FormData();
        formdata.append("file-upload", currentFile);
        
        const ajax = new XMLHttpRequest();

        // 监听上传进度
        ajax.upload.addEventListener("progress", (event) => {
            if (event.lengthComputable) {
                const percent = (event.loaded / event.total) * 100;
                progressBar.value = Math.round(percent);
            }
        });

        // 单个文件上传完成后处理下一个
        ajax.addEventListener("load", () => {
            if (ajax.status === 200) {
                currentFileIndex++;
                progressBar.value = 0; // 重置进度条
                uploadNextFile();
            } else {
                statusText.textContent = `Error al subir ${currentFile.name}, código: ${ajax.status}`;
            }
        });

        // 网络错误处理
        ajax.addEventListener("error", () => {
            statusText.textContent = `Error de red al subir ${currentFile.name}`;
        });

        ajax.open("POST", "pruebas.php");
        ajax.send(formdata);
    }

    // 启动第一个文件上传
    uploadNextFile();
});

关键修改说明

  • 串行上传逻辑:用递归函数uploadNextFile替代原循环,只有当前文件上传完成(触发load事件)后,才会启动下一个文件的上传,解决进度条混乱问题。
  • 进度与状态反馈:新增进度条和状态文本,实时显示当前上传的文件名、进度及总进度。
  • 完成判断:当currentFileIndex等于文件总数时,触发隐藏提交按钮提交表单。
  • 错误处理:添加网络错误和服务器错误监听,及时反馈上传异常。

内容的提问来源于stack exchange,提问作者leesin koreano

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 20:36:38