You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 14:25:32