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

如何通过jQuery二次请求实现带XHR进度条的文件上传?

嘿,我明白你已经搞定了带XHR进度条的单请求文件上传,现在想要通过第二次jQuery请求实现文件上传相关的需求——不管是分批次传大文件、先拿上传权限再执行上传,还是上传完成后触发二次校验,我给你几个贴合你现有代码结构的实用方案:

方案1:分批次上传大文件(两次请求拆分文件)

如果是要把大文件拆成两部分分两次上传,你可以复用现有的XHR进度逻辑,只需要给Upload类加一个分片处理的方法,然后依次发起两次AJAX请求:

// 扩展你的Upload类
Upload.prototype.uploadInChunks = function(file) {
    const chunkSize = 1024 * 1024 * 5; // 5MB分片
    const totalChunks = Math.ceil(file.size / chunkSize);
    let currentChunk = 0;

    // 定义分片上传逻辑,自动触发第二次请求
    const uploadChunk = () => {
        const start = currentChunk * chunkSize;
        const end = Math.min(start + chunkSize, file.size);
        const chunk = file.slice(start, end);
        
        const formData = new FormData();
        formData.append('fileChunk', chunk);
        formData.append('chunkIndex', currentChunk);
        formData.append('totalChunks', totalChunks);
        formData.append('fileName', file.name);

        $.ajax({
            url: "../Services/upload.ashx",
            type: "POST",
            data: formData,
            cache: false,
            contentType: false,
            processData: false,
            timeout: 60000,
            xhr: () => {
                const myXhr = $.ajaxSettings.xhr();
                if (myXhr.upload) {
                    // 复用你已有的进度处理方法,可额外传递分片信息
                    myXhr.upload.addEventListener('progress', (e) => {
                        this.progressHandling(e, currentChunk, totalChunks);
                    }, false);
                }
                return myXhr;
            },
            success: () => {
                currentChunk++;
                if (currentChunk < totalChunks) {
                    // 触发第二次(或后续)上传请求
                    uploadChunk();
                } else {
                    alert('文件上传完成');
                }
            },
            error: (err) => {
                console.error('分片上传失败', err);
            }
        });
    };

    // 启动第一次上传
    uploadChunk();
};

// 扩展进度处理方法,支持分片进度展示
Upload.prototype.progressHandling = function(event, chunkIndex = 0, totalChunks = 1) {
    if (event.lengthComputable) {
        // 单分片进度
        const chunkPercent = Math.round((event.loaded / event.total) * 100);
        // 整体进度
        const totalPercent = Math.round(((chunkIndex * 100) + chunkPercent) / totalChunks);
        console.log(`整体进度:${totalPercent}%,当前分片进度:${chunkPercent}%`);
        // 这里替换成你的DOM更新逻辑
    }
};
方案2:先发起预请求拿上传凭证,再执行实际上传

如果需要先通过第一次请求获取上传权限、token或其他参数,再用第二次请求完成文件上传:

Upload.prototype.uploadWithPreRequest = function(file) {
    // 第一次请求:获取上传凭证
    $.ajax({
        url: "../Services/getUploadToken.ashx",
        type: "GET",
        success: (tokenData) => {
            // 第二次请求:带凭证上传文件
            const formData = new FormData();
            formData.append('file', file);
            formData.append('uploadToken', tokenData.token);

            $.ajax({
                url: "../Services/upload.ashx",
                type: "POST",
                data: formData,
                cache: false,
                contentType: false,
                processData: false,
                timeout: 60000,
                xhr: () => {
                    const myXhr = $.ajaxSettings.xhr();
                    if (myXhr.upload) {
                        myXhr.upload.addEventListener('progress', this.progressHandling, false);
                    }
                    return myXhr;
                },
                success: () => {
                    alert('文件上传成功');
                },
                error: (err) => {
                    console.error('上传失败', err);
                }
            });
        },
        error: (err) => {
            console.error('获取上传凭证失败', err);
        }
    });
};
方案3:上传完成后触发二次校验/通知请求

如果是第一次请求完成文件上传后,需要发起第二次请求通知后端处理文件或校验上传结果:

// 基于你现有的上传代码改造
$.ajax({
    url: "../Services/upload.ashx",
    type: "POST",
    data: formData,
    cache: false,
    contentType: false,
    processData: false,
    timeout: 60000,
    xhr: function () {
        var myXhr = $.ajaxSettings.xhr();
        if (myXhr.upload) {
            myXhr.upload.addEventListener('progress', that.progressHandling, false);
        }
        return myXhr;
    },
    success: (uploadResult) => {
        // 第一次上传成功后,发起第二次校验请求
        $.ajax({
            url: "../Services/verifyUpload.ashx",
            type: "POST",
            data: {
                fileId: uploadResult.fileId,
                fileName: uploadResult.fileName
            },
            success: (verifyResult) => {
                if (verifyResult.success) {
                    alert('文件上传并校验完成');
                } else {
                    alert('文件校验失败,请重新上传');
                }
            },
            error: (err) => {
                console.error('校验请求失败', err);
            }
        });
    },
    error: (err) => {
        console.error('上传失败', err);
    }
});

注意事项

  • 不管哪种方案,都要确保后端upload.ashx(或对应接口)支持对应的逻辑:比如分片上传需要后端合并分片,预请求需要后端生成凭证,二次校验需要后端验证文件完整性。
  • 你可以直接复用现有progressHandling方法,只需要根据场景调整进度计算逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:58:10