Node-TS项目调用Home Depot API时GET请求无限挂起
Home Depot API请求无限挂起问题排查与解决
我有一个Node-TypeScript项目,从谷歌表格拉取宜家、Home Depot、亚马逊等平台的商品链接,通过fetch/axios调用接口获取商品信息后存回表格。大部分请求正常,但部分Home Depot的API请求会无限挂起,既不超时也不抛出错误。
已尝试的方案:
- 切换使用node-fetch与axios,问题复现
- 降级node-fetch至v2版本,无效
- 添加不同的User-Agent、Accept请求头,无改善
相关代码示例:
try { const productNumber = extractHomeDepotProductNumber(url); if (!productNumber) continue; const headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 'Accept-Encoding': 'gzip, deflate, br', } const res = await axios.get( `https://www.homedepot.ca/api/productsvc/v1/products/${productNumber}/store/7142?fields=BASIC_SPA&lang=en`, {headers} ); console.log('I got res') // 从未打印 const resWithImage = await axios.get( `https://www.homedepot.ca/api/fbtsvc/v1/fbt/products/${productNumber}/store/7142?checkStockAndPrice=true&lang=en`, {headers} ); console.log('I got resWithImage') } catch (error) { console.log(error) // 从未打印 }
问题示例对应的商品URL:https://www.homedepot.ca/product/kraus-mateosingle-lever-pull-down-kitchen-faucet-chrome/1000860141,其API请求会挂起。
补充:最初用Bun本地开发时正常,但构建后也出现相同问题。
可行解决方向
1. 强制设置请求超时
不管用axios还是node-fetch,必须明确设置超时时间,避免请求无限挂起:
- axios配置示例:
const res = await axios.get(url, { headers, timeout: 10000 // 10秒超时 });
- node-fetch用
AbortController手动控制超时:
const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 10000); try { const res = await fetch(url, { headers, signal: controller.signal }); clearTimeout(timeoutId); // 处理响应逻辑 } catch (err) { if (err.name === 'AbortError') { console.log('请求超时,终止挂起'); } else { throw err; } }
2. 禁用HTTP长连接
Home Depot的API可能对长连接的处理存在兼容问题,尝试禁用连接复用:
import http from 'http'; const agent = new http.Agent({ keepAlive: false, // 关闭长连接 maxSockets: 10 }); const res = await axios.get(url, { headers, httpAgent: agent, timeout: 10000 });
3. 补充完整请求头
模拟更真实的浏览器请求,添加缺失的常见头:
const headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'en-US,en;q=0.9', 'Connection': 'close' };
4. 限制并发请求数
Node.js默认HTTP连接池有数量限制,并发过高会导致请求排队挂起,用工具库限制并发:
import pLimit from 'p-limit'; const limit = pLimit(5); // 同时最多处理5个请求 // 处理每个商品链接时用limit包裹 await limit(async () => { // 你的API请求逻辑 });
5. 排查Bun构建环境差异
Bun本地与构建后的环境可能存在HTTP客户端配置差异,构建后显式禁用HTTP/2或指定TLS版本:
// Bun环境下强制使用HTTP/1.1 const res = await fetch(url, { headers, httpVersion: '1.1' });
内容的提问来源于stack exchange,提问作者Augusto Peres
相关产品推荐
相关产品推荐

