Node/Express/Axios应用中出现localhost未返回数据(ERR_EMPTY_RESPONSE)问题求助
Node/Express/Axios应用中出现localhost未返回数据(ERR_EMPTY_RESPONSE)问题求助
嘿,这个问题确实是异步处理逻辑+Express中间件的正确使用方式出了问题,我来帮你一步步搞定:
问题根源拆解
- 你的
searchArt不是合格的Express中间件:它没有接收Express中间件必须的req, res, next三个参数,完全没法和Express的请求生命周期打通——既没法把API数据传递给后续路由,也没法告诉Express“我这个异步请求干完了,继续往下走”。 - 异步操作未被等待:Axios请求是异步的,但
searchArt既没返回Promise,也没做任何等待处理,Express会直接跳过这个异步操作,执行后面的res.send(res.data)——但此时res.data根本不存在,而且异步请求还没完成,响应一直没发出去,最终导致浏览器超时报错。 - 路由里的
res.send(res.data)是错误用法:Express的res对象本身没有data属性,你得把API拿到的数据存在请求/响应的上下文里(比如res.locals)才能在后续逻辑里用。
修改后的代码方案
第一步:修复models/metData.js,把searchArt改成标准中间件
这里我用async/await让异步逻辑更清晰,你也可以用.then/.catch的写法,效果一样:
'use strict'; import axios from "axios"; const metAPI = { // 改成Express中间件形式,接收req, res, next参数 searchArt: async function(req, res, next) { try { // 等待Axios请求完成 const response = await axios.get("https://collectionapi.metmuseum.org/public/collection/v1/objects/11"); // 把API返回的数据存到res.locals(Express专门用来存中间件共享数据的地方) res.locals.artData = response.data; // 调用next,告诉Express可以执行下一个路由处理逻辑了 next(); } catch (error) { console.error('获取数据出错:', error); // 把错误传递给Express的全局错误处理中间件(如果有的话) next(error); } } }; export default metAPI;
第二步:修复routes/met_route.js,从上下文里取数据并返回
'use strict'; import express from "express"; import metData from "../models/metData.js"; const router = express.Router(); router.get('/', metData.searchArt, (req, res) => { // 从res.locals里拿到之前存的API数据,发送给客户端 res.send(res.locals.artData); }) export default router;
另一种简化方案(直接在中间件里发响应)
如果你的路由逻辑不需要额外处理数据,也可以直接在searchArt里发送响应,省去后续的路由处理函数:
// models/metData.js 简化版 searchArt: async function(req, res) { try { const response = await axios.get("https://collectionapi.metmuseum.org/public/collection/v1/objects/11"); // 直接在这里把数据发给客户端 res.send(response.data); } catch (error) { console.error('获取数据出错:', error); // 给客户端返回错误状态码和提示 res.status(500).send({ message: '获取艺术品数据失败', error: error.message }); } } // routes/met_route.js 简化版 router.get('/', metData.searchArt);
这样修改后,Express会等待异步请求完成后再发送响应,就不会出现超时和空响应的问题啦~
备注:内容来源于stack exchange,提问作者James Johnson




