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

如何在Next.js项目中将Formidable接收的文件转为Base64并发送至Odoo

Next.js 表单文件直转Base64传Odoo问题解决

问题背景

构建Next.js项目,流程为:前端通过axios将含文件的表单数据以FormData形式发送至后端,后端通过xmlrpc将数据转发至Odoo ERP。核心需求是不将文件存储在服务器,直接转为Odoo兼容的Base64格式发送。

前端代码

const SubmitHandeler = (values) => {
    const formdata = new FormData();
    formdata.append('nom', values.nom);
    formdata.append('prenom', values.prenom);
    formdata.append('email', values.email);
    formdata.append('phone', values.phone);
    values.files.forEach((file) => {
        formdata.append(`file`, file);
    });
    setUploading(true);
    axios.post("/api/upload", formdata, {
        onUploadProgress: (progressEvent) => {
            const progressPercent = Math.round(
                (progressEvent.loaded * 100) / progressEvent.total
            );
            setProgress(progressPercent);
        },
    }).then((result) => {
        setUploading(false);
        // router.push('/');
        console.log(result.data);
    }).catch((err) => {
        setUploading(false);
        console.log(err)
    });
}

后端问题

使用formidable解析请求时遇到两个问题:

  • 在formidable.IncomingForm构造函数中设置encoding: "base64",解析得到的文件数组为空
  • 不设置编码时,文件数组有内容,但formidable.File类型的toString()方法无法指定编码转换为Base64(与fs模块的file.toString("base64")行为不同)

后端原代码:

export default async function handeler(req, res) {
    const form = new formidable.IncomingForm({ multiples: true, encoding: "base64" });

    const formData = new Promise((resolve, reject) => {
        form.parse(req, async (err, fields, files) => {
            if (err) {
                reject("error");
            }
            resolve({ fields, files });
        });
    });

    const { fields, files } = await formData;
    //SEND TO ODOO
    send_data_to_odoo(/*args*/)
    res.status(200).json({ msg: "done" })
}

已尝试无效方案

  • 使用multer:不符合需求,multer会将文件存储到文件系统
  • 前端使用const base64String = Buffer.from(fileData).toString('base64');转码:无效
  • 使用file.toString():转换结果不被Odoo接受

解决方案

不设置encoding,通过读取formidable生成的临时文件Buffer来转换Base64,转换完成后可删除临时文件避免存储冗余:

import fs from 'fs';

export default async function handler(req, res) {
    const form = new formidable.IncomingForm({ multiples: true }); // 移除encoding配置

    const formData = new Promise((resolve, reject) => {
        form.parse(req, (err, fields, files) => {
            if (err) {
                reject("表单解析失败");
                return;
            }
            resolve({ fields, files });
        });
    });

    const { fields, files } = await formData;
    const base64Files = [];

    // 处理单个或多个文件的情况
    const fileList = Array.isArray(files.file) ? files.file : [files.file];
    for (const file of fileList) {
        // 读取临时文件的Buffer
        const fileBuffer = fs.readFileSync(file.filepath);
        // 转换为Base64字符串
        const base64Str = fileBuffer.toString('base64');
        base64Files.push({
            filename: file.originalFilename,
            base64: base64Str,
            mimetype: file.mimetype
        });
        // 可选:删除临时文件,释放服务器空间
        fs.unlinkSync(file.filepath);
    }

    // 将字段和Base64文件数据发送至Odoo
    send_data_to_odoo(fields, base64Files);

    res.status(200).json({ msg: "done" });
}

说明

  • 不设置encoding,让formidable正常将文件写入临时路径
  • 通过fs.readFileSync读取临时文件的Buffer,再用toString('base64')生成Odoo兼容的Base64字符串
  • 转换完成后调用fs.unlinkSync删除临时文件,避免服务器存储无用文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:25:33