Express路由接收FormData文件时出现404及JSON解析错误求助
看起来你遇到的问题主要出在multer配置不匹配、中间件顺序错误,以及fetch响应处理不严谨这几个地方,我来一步步帮你解决:
1. 修正multer的文件字段配置
你当前用了multer({storage}).array('image', 12),但你的FormData里的文件字段是photo和cover,完全不匹配,导致multer无法正确解析文件,请求没法走到你的路由控制器,最终返回404。
改成用fields()方法指定多个文件字段,更符合你的场景:
// 先定义multer上传配置(单独提取出来,不要全局挂载) const upload = multer({ storage }).fields([ { name: 'photo', maxCount: 1 }, // 对应FormData里的photo字段,最多1个文件 { name: 'cover', maxCount: 1 } // 对应FormData里的cover字段,最多1个文件 ]);
然后把这个upload作为路由的专属中间件,而不是全局挂载:
// 路由代码修改 router.post('/update', upload, account.update);
2. 调整中间件顺序,移除全局multer
全局挂载multer会让所有请求都经过文件解析逻辑,这不仅没必要,还可能干扰普通请求。同时bodyParser.json()会尝试解析multipart/form-data类型的请求(但它处理不了),导致把服务器返回的404错误页面(HTML格式)当成JSON解析,出现Unexpected token <的错误。
修正后的中间件顺序:
server.use(express.static(path.resolve(__dirname, '../public'))); // 先处理urlencoded表单(和multer不冲突) server.use(bodyParser.urlencoded({ extended: false })); // 只处理application/json类型的请求 server.use(bodyParser.json()); // 最后挂载路由(路由里已经包含了需要的multer中间件) server.use('/', router);
3. 检查请求路径是否匹配
确认你Auth.fetch('/update')的路径和路由的/update完全匹配,如果你的Express服务器有前缀(比如/api),路径要写成/api/update。可以在开发者工具的"Network"标签里查看请求的完整URL,确保没有拼写错误。
4. 完善fetch的响应处理逻辑
当服务器返回404时,fetch不会直接进入catch,而是会进入then,但此时响应体是HTML,调用res.json()就会抛出解析错误。所以要先检查响应的状态:
saveUpdate = () => { const formData = new FormData(); const { user, Auth } = this.props; formData.append('user_id', user.id); formData.append('photo', this.photo_ref.files[0]); formData.append('cover', this.cover_ref.files[0]); Auth.fetch('/update', { method: "POST", credentials: 'same-origin', body: formData, }) .then(res => { // 先检查响应是否成功 if (!res.ok) { throw new Error(`请求失败,状态码:${res.status}`); } return res.json(); }) .then(data => { if(data.code === 200){ console.log(data) } }) .catch(err => console.log(err)); }
做完这些修改后,应该就能正常解析文件并获取响应了。你可以在控制器里打印req.files,会看到photo和cover对应的文件信息。
内容的提问来源于stack exchange,提问作者JEEZSUSCRIZE

