从request库迁移至node-fetch后出现504网关超时错误求助
问题:node-fetch替换request后出现504 Gateway Timeout错误
原本使用request库的代码(无async/await)运行正常,改用node-fetch结合async/await重写后出现504 Gateway Timeout错误,请求帮忙排查。相关代码如下:
const fetch = require("node-fetch").default; let iApi = express.Router(); iApi.post("/update/:name/:value", async (req, res) => { const name = req.params["name"]; const value = req.params["value"]; const headers = { ...req.headers }; const url = `${process.env.URL}/name/${name}/value/${value}`; const options = { url: url, method: "post", headers: headers, gzip: true, }; //if (process.env.NODE_ENV === "development") { // options.agent = agent; //} // request(options, function(err, response, body) { // handleResponseNoBody(err, response, body, res, url) // }) const response = await fetch(url, options); if (response.status == 200) { logger.info({ ...LOG_DEFAULTS, endpoint: url, methodName: "update", description: "update", c_id: req.cId, res, req, }); const data = await response.json(); res.send(data); } else { res.status(response.status).send(JSON.parse(data)); } });
解决方案
问题出在混用了request和node-fetch的参数格式,以及部分请求配置的细节差异,以下是修正后的代码和关键修改说明:
修正后的代码
const fetch = require("node-fetch").default; let iApi = express.Router(); iApi.post("/update/:name/:value", async (req, res) => { const name = req.params["name"]; const value = req.params["value"]; // 过滤可能引发冲突的请求头,避免上游服务器拒绝 const headers = {...req.headers}; delete headers.host; delete headers["content-length"]; const url = `${process.env.URL}/name/${name}/value/${value}`; const options = { method: "POST", // 遵循HTTP方法大写规范 headers: headers, compress: true, // node-fetch标准的压缩处理,替代request的gzip: true // 开发环境需要agent的话取消注释,确保agent已正确初始化 // agent: process.env.NODE_ENV === "development" ? agent : undefined }; try { const response = await fetch(url, options); // 统一解析响应body,避免分支中变量未定义 const data = await response.json(); if (response.status === 200) { logger.info({ ...LOG_DEFAULTS, endpoint: url, methodName: "update", description: "update", c_id: req.cId, res, req, }); res.send(data); } else { res.status(response.status).send(data); } } catch (err) { // 捕获请求超时、网络错误等异常 logger.error({ ...LOG_DEFAULTS, endpoint: url, methodName: "update", error: err.message, c_id: req.cId, }); res.status(504).send({error: "请求超时或上游服务不可用"}); } });
关键修改点
- 参数格式修正:node-fetch的初始化对象不需要
url字段,url直接作为第一个参数传入,原代码中options.url是request的专属参数格式,会导致node-fetch配置错误 - 压缩处理替换:将request的
gzip: true替换为node-fetch标准的compress: true,它会自动处理gzip压缩的响应 - 请求头过滤:移除了
host、content-length等可能引发冲突的请求头,避免上游服务器因为头信息异常拒绝请求 - 异常处理补充:添加
try/catch捕获请求过程中的网络错误、超时等异常,避免未处理的崩溃 - 响应逻辑修正:统一解析响应body,else分支不再使用未定义的
data变量 - Agent配置恢复:如果开发环境依赖自定义Agent,取消注释相关代码,request可能依赖这个Agent处理长连接或代理,注释后可能导致超时
内容的提问来源于stack exchange,提问作者shoes_on
相关产品推荐
相关产品推荐

