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

Next.js中PDF简历上传后端无法获取数据的解决求助

解决Next.js中PDF简历上传时后端无法获取表单数据的问题

你在Next.js项目中实现PDF上传时,前端能看到完整表单数据,但后端只能拿到[object Object],禁用bodyParser后完全接收不到数据,核心问题在于前端没有正确构造FormData,且Next.js默认body parser不支持multipart/form-data解析,以下是具体修复方案:


一、前端代码修正

当前你传递的是普通JavaScript对象而非原生FormData实例,且手动设置Content-Type会覆盖浏览器自动生成的带boundary的请求头,导致后端解析失败。

1. 调整提交逻辑,构造真实FormData

修改组件中的handleSubmit方法,将状态对象转为FormData实例:

export default function ApplyJob() {
    // 重命名状态变量避免和FormData冲突
    const [formDataState, setFormDataState] = useState({ 
        name: '', email: "", about: '', job: id, user: user?._id, cv: null 
    });

    const handleSubmit = async (e) => {
        e.preventDefault();

        // 省略原有校验逻辑...

        // 构造FormData实例并添加字段
        const formData = new FormData();
        formData.append('name', formDataState.name);
        formData.append('email', formDataState.email);
        formData.append('about', formDataState.about);
        formData.append('job', formDataState.job);
        formData.append('user', formDataState.user);
        formData.append('cv', formDataState.cv);

        console.log(formData);
        const res = await apply_job(formData);
        // 后续逻辑...
    }

    // 其余代码保持不变,仅将setFormData改为setFormDataState
}

2. 修改请求函数,移除手动设置的Content-Type

export const apply_job = async (formData) => {
    console.log(formData)
    try {
        const res = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/job/applyJob`, {
            method: 'POST',
            // 移除手动设置的Content-Type,浏览器会自动添加带boundary的正确请求头
            body: formData,
        });
        const data = await res.json();
        return data;
    } catch (error) {
        console.log('error in apply job (service) => ', error);
    }
}

二、后端代码修正

Next.js默认的body parser无法解析multipart/form-data格式,需要禁用默认配置,使用formidable库解析表单和文件。

1. 安装formidable依赖

npm install formidable
# 或
yarn add formidable

2. 修改API路由,禁用bodyParser并解析FormData

import ConnectDB from '@/DB/connectDB';
import AppliedJob from '@/models/ApplyJob';
import Joi from 'joi';
import { IncomingForm } from 'formidable';

const schema = Joi.object({
    name: Joi.string().required(),
    email: Joi.string().email().required(),
    about: Joi.string().required(),
    job: Joi.string().required(),
    user: Joi.string().required(),
});

// 禁用默认bodyParser
export const config = {
    api: {
        bodyParser: false,
    }
}

export default async (req, res) => {
    await ConnectDB();

    if (req.method !== 'POST') {
        return res.status(405).json({ success: false, message: 'Method not allowed' });
    }

    // 初始化formidable,设置文件大小限制
    const form = new IncomingForm({
        maxFileSize: 50 * 1024 * 1024, // 50MB
    });

    form.parse(req, async (err, fields, files) => {
        if (err) {
            console.log('Error parsing form data => ', err);
            return res.status(500).json({ success: false, message: 'Failed to parse form data' });
        }

        // 打印解析后的字段和文件
        console.log('Form fields:', fields);
        console.log('Uploaded CV:', files.cv);

        // 校验表单字段(formidable返回的字段是数组,需取[0])
        const { error } = schema.validate({
            name: fields.name[0],
            email: fields.email[0],
            about: fields.about[0],
            job: fields.job[0],
            user: fields.user[0],
        });

        if (error) {
            return res.status(401).json({ 
                success: false, 
                message: error.details[0].message.replace(/['"]+/g, '') 
            });
        }

        try {
            // 可在此处理文件,例如保存到服务器或云存储
            const cvFilePath = files.cv[0].filepath;
            
            // 创建申请记录,存储必要信息
            await AppliedJob.create({
                user: fields.user[0],
                job: fields.job[0],
                name: fields.name[0],
                email: fields.email[0],
                about: fields.about[0],
                cv: cvFilePath, // 或存储文件名、访问URL等
            });

            return res.status(200).json({ 
                success: true, 
                message: "Job Applied Successfully !" 
            });
        } catch (error) {
            console.log('Error in applying job (server) => ', error);
            return res.status(500).json({ 
                success: false, 
                message: "Something Went Wrong Please Retry Later !" 
            });
        }
    });
}

关键说明

  • 前端必须使用FormData实例传递含文件的表单数据,普通JS对象无法携带文件信息。
  • 禁止手动设置Content-Type: multipart/form-data,浏览器会自动生成带boundary的请求头,这是后端正确解析的关键。
  • 后端必须禁用默认bodyParser,使用专门的multipart解析库(如formidable)处理文件上传。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 12:22:55