使用Axios在React中上传文件时无法向Node后端发送FormData对象的问题
问题根因&解决方案
1. 前端请求头配置错误
你手动指定了Content-Type: multipart/form-data,但multipart/form-data类型的请求头必须附带boundary边界参数用于分隔请求体中的不同字段,手动写死请求头会导致axios无法自动生成带boundary的合法请求头,服务端自然无法正常解析请求体。
修复方法:删除axios配置中的headers项,axios发送FormData类型数据时会自动补全正确的请求头
修改后前端上传代码:
fileUploadHandler(e) { e.preventDefault(); e.stopPropagation(); let file = this.state.selectedFile; // 可选校验,确认文件确实被正确获取 if (!file) return console.log('未选择文件'); let formData = new FormData(); formData.append('image', file); formData.append('name', file.name); axios({ url: 'http://localhost:3001/uploadLoaf', method: 'POST', data: formData }) .then(respo => console.log(respo)) .catch(err => console.log(err)) }
2. 服务端未正确挂载multer中间件
Express原生不解析multipart/form-data类型的请求体,哪怕你安装了multer,没有在对应路由上挂载中间件也无法拿到数据。
修复方法:先配置multer,再给路由挂载对应的中间件
首先安装multer:
npm i multer
服务端完整配置代码:
const express = require('express'); const multer = require('multer'); const app = express(); // 因为你需要把文件转发给Firebase云函数,不需要存本地磁盘,所以用内存存储即可 const storage = multer.memoryStorage(); // single('image')对应你前端FormData里append的文件字段名image const upload = multer({ storage: storage }).single('image'); // 注意:express.json()和express.urlencoded()只能解析json和表单urlencoded格式,对文件上传无效 app.use(express.json()); app.post('/uploadLoaf', upload, (req, res) => { console.log('uploadLoaf endpoint reached'); // 普通文本字段在req.body中,比如你传的name字段 console.log('文本字段:', req.body); // 上传的文件信息在req.file中,文件二进制内容存在req.file.buffer里 console.log('上传文件信息:', req.file); // 转发给Firebase云函数的逻辑可以直接用req.file.buffer构造新的FormData即可 res.status(201).json('complete') }); app.listen(3001, () => console.log('服务启动在3001端口'))
补充校验
确认你的fileSelectedHandler方法正确给this.state.selectedFile赋值,示例代码参考:
fileSelectedHandler = (e) => { this.setState({ selectedFile: e.target.files[0] }) }
内容的提问来源于stack exchange,提问作者Callum Reid
相关产品推荐
相关产品推荐

