使用Axios发送Put请求携带FormData时出现undefined is not Json错误
使用Axios发送带FormData的PUT请求时出现「undefined is not Json」错误的解决
问题描述
使用Axios发送携带FormData对象的PUT请求后,出现「undefined is not Json」错误。已确认前端updatedData不为空且包含所需数据,但后端console.log(req.body)显示req.body={}为空对象,进而触发错误。
相关代码
updatedData构建代码
const urlToObject = async (url) => { let response = await fetch(url); let blob = await response.blob(); return new File([blob], data?.photo, { type: blob.type }); }; const picture = await urlToObject(STABLES.UPLOAD_FOLDER_BASE_URL + data?.photo); updatedData.append("mainPhoto", picture); const emptyDocument = JSON.stringify({ title: "", caption: "", slug: "", body: "", tags: [], categories: [], }); updatedData.append("document", emptyDocument);
请求函数代码
const updatePost = async ({ updatedData, slug, token }) => { try { const config = { headers: { "Content-Type": "multipart/form-data", Authorization: `Bearer ${token}`, } }; const { data } = await axios.put(`/api/posts/${slug}`, updatedData, config); return data; } catch (e) { if(e.response && e.response.data.message) { throw new Error(e.response.data.message); } throw new Error(e.message); } };
已尝试的无效方案
- 修改Content-Type为
application/x-www-form-urlencoded - 修改Content-Type为
application/json,此时仅能获取req.body.document,但无法拿到mainPhoto图片文件 - 在server.js中添加以下Express中间件,问题未解决:
app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use(express.json({ limit: '10mb' })); app.use(express.urlencoded({ limit: '10mb', extended: true }));
正确解决方案
前端调整
不要手动设置Content-Type: multipart/form-data,Axios会自动为FormData请求添加包含边界符boundary的正确Content-Type,手动设置会丢失边界信息,导致后端无法解析。修改请求函数如下:
const updatePost = async ({ updatedData, slug, token }) => { try { const config = { headers: { Authorization: `Bearer ${token}`, // 移除手动设置的Content-Type } }; const { data } = await axios.put(`/api/posts/${slug}`, updatedData, config); return data; } catch (e) { if(e.response && e.response.data.message) { throw new Error(e.response.data.message); } throw new Error(e.message); } };
后端调整
Express默认的express.json()和express.urlencoded()无法解析multipart/form-data类型请求,需使用multer中间件处理文件上传:
- 安装multer:
npm install multer - 在后端路由中配置multer:
若需持久化存储文件,可配置multer的磁盘存储引擎:const multer = require('multer'); const upload = multer(); // 默认将文件暂存到内存,可按需修改存储方式 // 在PUT请求路由中使用upload中间件 app.put('/api/posts/:slug', upload.any(), (req, res) => { // req.body 包含document字段(需手动转为JSON) // req.files 包含mainPhoto文件对象 const document = JSON.parse(req.body.document); const mainPhoto = req.files.find(file => file.fieldname === 'mainPhoto'); // 后续业务逻辑处理 });const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, 'uploads/') // 指定存储目录,需提前创建 }, filename: function (req, file, cb) { cb(null, Date.now() + '-' + file.originalname) // 生成唯一文件名 } }); const upload = multer({ storage: storage });
内容的提问来源于stack exchange,提问作者Abdo Rabah
相关产品推荐
相关产品推荐

