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

使用Axios上传Base64时Promise对象传递异常问题排查

问题:Base64转换后后端收到Promise对象而非实际字符串

我找到的Base64转换函数都依赖Promise,于是写了一个返回Promise的getBase64函数,用await等待转换结果后返回。但提交表单时,后端收到的文件内容还是Promise对象,明显await没起作用。

代码示例

getBase64: async (file) => {
    let data = await new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => resolve(reader.result);
        reader.onerror = (error) => reject(error);
    })
    return data
},
submitHistoricalPreprint() {
    
    if (this.$refs['AddHistoricalPreprintForm'].validate()) {

        let form = new FormData()

        this.historicalPreprintDocs.forEach((round, index) => {

            form.append(`data[${index}].ppid`, this.selectPPID.PPID)

            form.append(`data[${index}].round`, round.round)

            if (round.preprint) {
                form.append(`data[${index}].preprint.fileName`, round.preprint.name)
                form.append(`data[${index}].preprint.content`, this.getBase64(round.preprint))
            } else {
                form.append(`data[${index}].preprint`, null)
            }

            round.supportingDocumentation ? round.supportingDocumentation.forEach((file, index2) => {
                form.append(`data[${index}].supportingDocumentation[${index2}].fileName`, file.name)
                form.append(`data[${index}].supportingDocumentation[${index2}].content`, this.getBase64(file))
            }) : form.append(`data[${index}].supportingDocumentation`, null)

            if (round.oactQuestions) {
                form.append(`data[${index}].oactQuestions.fileName`, round.oactQuestions.name)
                form.append(`data[${index}].oactQuestions.content`, this.getBase64(round.oactQuestions))
            } else {
                form.append(`data[${index}].oactQuestions`, null)
            }

            round.cmcsResponses ? round.cmcsResponses.forEach((file,index2) => {
                form.append(`data[${index}].cmcsResponses[${index2}].fileName`, file.name)
                form.append(`data[${index}].cmcsResponses[${index2}].content`, this.getBase64(file))

            }) : form.append(`data[${index}].cmcsResponses`, null)

            if (round.stateResponses) {
                form.append(`data[${index}].stateResponses.fileName`, round.stateResponses.name)
                form.append(`data[${index}].stateResponses.content`, this.getBase64(round.stateResponses))
            } else {
                form.append(`data[${index}].stateResponses`, null)
            }

            if (round.approvalLetter) {
                form.append(`data[${index}].approvalLetter.fileName`, round.approvalLetter.name)
                form.append(`data[${index}].approvalLetter.content`, this.getBase64(round.approvalLetter))
            } else {
                form.append(`data[${index}].approvalLetter`, null)
            }
        })

        axios({
            method: 'post',
            url: window.location.origin + '/Preprint/UploadHistoricalReview',
            data: form,
            headers: {
                'Content-Type': 'multipart/form-data',
                "RequestVerificationToken": document.forms[0].querySelector('input[name="__RequestVerificationToken"]').value,
            }
        }).then(response => {
            this.historicalPreprintDocs = [{
                "round": 1,
                "preprint": null,
                "supportingDocumentation": [],
                "oactQuestions": null,
                "cmcsResponses": [],
                "stateResponses": null,
                "approvalLetter": null,
            }]
            this.$refs['AddHistoricalPreprintForm'].reset();

        }).catch(error => {
            if (error.response.status == 401 || error.response.status == 402 || error.response.status == 403) {
                window.location.href = error.response.headers.expiredtokenredirecturi
            }
            console.log(error.response.data.error);
        });
    }
},

问题原因

核心问题有两个:

  • submitHistoricalPreprint不是异步函数,无法在内部使用await等待getBase64的转换结果
  • forEach循环不支持异步回调阻塞,直接调用this.getBase64(file)会直接返回Promise对象,而非解析后的Base64字符串,导致FormData中存储的是Promise而非实际内容

解决方案

  1. 将submitHistoricalPreprint声明为async函数
  2. 把forEach替换为for...of循环,支持在循环内部使用await等待异步操作完成
  3. 所有调用this.getBase64(file)的位置都添加await,确保拿到实际的Base64字符串

修改后的代码示例

getBase64: async (file) => {
    // 简化函数,直接返回Promise即可
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => resolve(reader.result);
        reader.onerror = (error) => reject(error);
    })
},
async submitHistoricalPreprint() {
    
    if (this.$refs['AddHistoricalPreprintForm'].validate()) {

        let form = new FormData()

        // 用for...of替代forEach,支持async/await
        for (const [index, round] of this.historicalPreprintDocs.entries()) {

            form.append(`data[${index}].ppid`, this.selectPPID.PPID)
            form.append(`data[${index}].round`, round.round)

            if (round.preprint) {
                form.append(`data[${index}].preprint.fileName`, round.preprint.name)
                // 等待Base64转换完成
                const preprintBase64 = await this.getBase64(round.preprint)
                form.append(`data[${index}].preprint.content`, preprintBase64)
            } else {
                form.append(`data[${index}].preprint`, null)
            }

            if (round.supportingDocumentation && round.supportingDocumentation.length > 0) {
                // 处理支持文档数组
                for (const [index2, file] of round.supportingDocumentation.entries()) {
                    form.append(`data[${index}].supportingDocumentation[${index2}].fileName`, file.name)
                    const docBase64 = await this.getBase64(file)
                    form.append(`data[${index}].supportingDocumentation[${index2}].content`, docBase64)
                }
            } else {
                form.append(`data[${index}].supportingDocumentation`, null)
            }

            if (round.oactQuestions) {
                form.append(`data[${index}].oactQuestions.fileName`, round.oactQuestions.name)
                const oactBase64 = await this.getBase64(round.oactQuestions)
                form.append(`data[${index}].oactQuestions.content`, oactBase64)
            } else {
                form.append(`data[${index}].oactQuestions`, null)
            }

            if (round.cmcsResponses && round.cmcsResponses.length > 0) {
                for (const [index2, file] of round.cmcsResponses.entries()) {
                    form.append(`data[${index}].cmcsResponses[${index2}].fileName`, file.name)
                    const cmcsBase64 = await this.getBase64(file)
                    form.append(`data[${index}].cmcsResponses[${index2}].content`, cmcsBase64)
                }
            } else {
                form.append(`data[${index}].cmcsResponses`, null)
            }

            if (round.stateResponses) {
                form.append(`data[${index}].stateResponses.fileName`, round.stateResponses.name)
                const stateBase64 = await this.getBase64(round.stateResponses)
                form.append(`data[${index}].stateResponses.content`, stateBase64)
            } else {
                form.append(`data[${index}].stateResponses`, null)
            }

            if (round.approvalLetter) {
                form.append(`data[${index}].approvalLetter.fileName`, round.approvalLetter.name)
                const approvalBase64 = await this.getBase64(round.approvalLetter)
                form.append(`data[${index}].approvalLetter.content`, approvalBase64)
            } else {
                form.append(`data[${index}].approvalLetter`, null)
            }
        }

        try {
            // 用await替代then/catch,代码更简洁
            const response = await axios({
                method: 'post',
                url: window.location.origin + '/Preprint/UploadHistoricalReview',
                data: form,
                headers: {
                    'Content-Type': 'multipart/form-data',
                    "RequestVerificationToken": document.forms[0].querySelector('input[name="__RequestVerificationToken"]').value,
                }
            })
            this.historicalPreprintDocs = [{
                "round": 1,
                "preprint": null,
                "supportingDocumentation": [],
                "oactQuestions": null,
                "cmcsResponses": [],
                "stateResponses": null,
                "approvalLetter": null,
            }]
            this.$refs['AddHistoricalPreprintForm'].reset();
        } catch (error) {
            if (error.response.status == 401 || error.response.status == 402 || error.response.status == 403) {
                window.location.href = error.response.headers.expiredtokenredirecturi
            }
            console.log(error.response.data.error);
        }
    }
},

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 08:14:55