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
相关产品推荐
相关产品推荐

