前端有效File对象在Express后端接收为空,求技术解决方案
问题:前端File对象在Express后端接收为空
前端发起请求时持有包含有效数据的File对象,但Express后端接收请求体时,该File对象为空。
前端代码如下:
let body = { metadata: { date: date, location: location, description: description, file: file } } const headers = {'body': JSON.stringify(body)} axios.get('/api/xummMint', {headers}).then( (res) => { console.log("xumm data coming"); console.log(res) setData({xummData: res}); })
后端打印req.headers.body得到的结果中file字段为空对象,尽管前端的File对象包含数据:
{"metadata":{"date":"2022-12-30","location":"asf","description":"asdf","file":{}}}
尝试过使用fetch并设置content-Type: application/json,结果依旧。
解决方案
核心问题原因
- JSON无法序列化File对象:
JSON.stringify()会把File对象序列化成空对象{},因为File属于浏览器特有的二进制对象,JSON不支持直接序列化这类二进制数据。 - GET请求不适合传二进制数据:GET请求的参数或头信息都不适合携带二进制文件,不仅有长度限制,设计上也不是用来传输文件的。
- 错误的请求体传递方式:你把请求体塞进了请求头的
body字段,这不符合HTTP规范,请求体应该放在请求的body部分,而非header中。
正确实现步骤
前端修改:使用FormData+POST请求
// 用FormData包装文本数据和文件 const formData = new FormData(); formData.append('date', date); formData.append('location', location); formData.append('description', description); formData.append('file', file); // 直接添加File对象 // 用POST请求发送FormData axios.post('/api/xummMint', formData) .then(res => { console.log("xumm data coming"); console.log(res); setData({xummData: res}); }) .catch(err => { console.error('请求出错:', err); });
注:axios会自动识别FormData并设置
Content-Type: multipart/form-data,无需手动配置。
后端修改:配置文件解析中间件
Express默认无法处理multipart/form-data类型的请求体,需要使用multer中间件解析文件:
- 安装multer:
npm install multer
- 在Express路由中配置:
const express = require('express'); const multer = require('multer'); const router = express.Router(); // 配置内存存储(也可改为磁盘存储,指定文件保存路径) const storage = multer.memoryStorage(); const upload = multer({ storage: storage }); // 处理POST请求,upload.single('file')表示接收名为file的单个文件 router.post('/api/xummMint', upload.single('file'), (req, res) => { // 文本字段在req.body中 const { date, location, description } = req.body; // 文件在req.file中,包含文件名、大小、二进制数据等信息 const file = req.file; console.log('接收的文本数据:', { date, location, description }); console.log('接收的文件:', file); // 后续业务逻辑... res.json({ success: true, message: '数据接收成功' }); }); module.exports = router;
额外说明
如果需要传递结构化的metadata对象,可以先转成JSON字符串再添加到FormData:
formData.append('metadata', JSON.stringify({ date: date, location: location, description: description }));
后端接收时解析:
const metadata = JSON.parse(req.body.metadata);
内容的提问来源于stack exchange,提问作者AxelKong
相关产品推荐
相关产品推荐

