使用node-fetch通过HTTP/1.1调用电商URL超时问题求助
解决node-fetch调用电商URL的HTTP/1.1超时问题
问题背景
使用node-fetch调用dhgate、abercrombie这类电商平台URL时,部分HTTP/1.1请求出现超时,但相同参数的curl命令能成功完成请求。
可正常工作的curl示例
调用dhgate
curl -m 10 -v --http1.1 "https://www.dhgate.com" \ -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36" \ -H "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.98" \ -H "Accept-Encoding: gzip, deflate, br" \ -H "Connection: keep-alive" \ -H "Content-Type: application/json"
调用abercrombie
curl -m 10 -v --http1.1 "https://www.abercrombie.com/shop/us" \ -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36" \ -H "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.98" \ -H "Accept-Encoding: gzip, deflate, br" \ -H "Connection: keep-alive" \ -H "Content-Type: application/json"
node-fetch调试日志
HTTP 67536: createConnection www.dhgate.com:443::::::::::::::::::::: [Object: null prototype] { protocol: 'https:', slashes: true, auth: null, host: 'www.dhgate.com', port: 443, hostname: 'www.dhgate.com', hash: null, search: '?wgu=8477_127107_16977422063155_b7229050b9&wgexpiry=1729278206&f=bm%7Caff%7Cwg%7C55163%7C8477_127107_16977422063155_b7229050b9%7C0%7C%7C%7Cus%7C%7C%7C&utm_source=webgains_us&utm_medium=Affiliate&utm_content=0&utm_campaign=affid', query: 'wgu=8477_127107_16977422063155_b7229050b9&wgexpiry=1729278206&f=bm%7Caff%7Cwg%7C55163%7C8477_127107_16977422063155_b7229050b9%7C0%7C%7C%7Cus%7C%7C%7C&utm_source=webgains_us&utm_medium=Affiliate&utm_content=0&utm_campaign=affid', pathname: '/product/fashion-women-sandals-summer-flats-sexy-ankle/479784035.html', path: null, href: 'https://www.dhgate.com/product/fashion-women-sandals-summer-flats-sexy-ankle/479784035.html?wgu=8477_127107_16977422063155_b7229050b9&wgexpiry=1729278206&f=bm%7Caff%7Cwg%7C55163%7C8477_127107_16977422063155_b7229050b9%7C0%7C%7C%7Cus%7C%7C%7C&utm_source=webgains_us&utm_medium=Affiliate&utm_content=0&utm_campaign=affid', method: 'GET', headers: [Object: null prototype] { 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.98' ], 'Accept-Encoding': [ 'gzip, deflate, br' ], Connection: [ 'keep-alive' ], 'User-Agent': [ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36' ], 'Content-Type': [ 'application/json' ] }, agent: undefined, _defaultAgent: Agent { _events: [Object: null prototype] { free: [Function (anonymous)], newListener: [Function: maybeEnableKeylog] }, _eventsCount: 2, _maxListeners: undefined, defaultPort: 443, protocol: 'https:', options: [Object: null prototype] { keepAlive: true, scheduling: 'lifo', timeout: 5000, noDelay: true, path: null }, requests: [Object: null prototype] {}, sockets: [Object: null prototype] { 'www.dhgate.com:443:::::::::::::::::::::': [] }, freeSockets: [Object: null prototype] { 'track.webgains.com:443:::::::::::::::::::::': [Array] }, keepAliveMsecs: 1000, keepAlive: true, maxSockets: Infinity, maxFreeSockets: 256, scheduling: 'lifo', maxTotalSockets: Infinity, totalSocketCount: 1, maxCachedSessions: 100, _sessionCache: { map: [Object], list: [Array] }, [Symbol(kCapture)]: false }, keepAlive: true, scheduling: 'lifo', timeout: 5000, noDelay: true, servername: 'www.dhgate.com', _agentKey: 'www.dhgate.com:443:::::::::::::::::::::' } NET 67536: pipe false null NET 67536: connect: find host www.dhgate.com NET 67536: connect: dns options { family: undefined, hints: 1024 } NET 67536: connect: autodetecting HTTP 67536: sockets www.dhgate.com:443::::::::::::::::::::: 1 2 HTTP 67536: outgoing message end. STREAM 67536: read 0 STREAM 67536: need readable false STREAM 67536: length less than watermark true STREAM 67536: do read NET 67536: _read - n 16384 isConnecting? true hasHandle? true NET 67536: _read wait for connection STREAM 67536: resume STREAM 67536: resume true STREAM 67536: flow true STREAM 67536: read undefined STREAM 67536: need readable true STREAM 67536: length less than watermark true STREAM 67536: reading, ended or constructing false NET 67536: connect/multiple: only one address found, switching back to single connection NET 67536: connect: attempting to connect to 23.44.84.179:443 (addressType: 4) NET 67536: afterConnect NET 67536: _read - n 16384 isConnecting? false hasHandle? true NET 67536: Socket._handle.readStart STREAM 67536: read 0 STREAM 67536: need readable true STREAM 67536: length less than watermark true STREAM 67536: reading, ended or constructing false STREAM 67536: onWriteComplete 0 undefined NET 67536: _onTimeout HTTP 67536: CLIENT socket onTimeout NET 67536: destroy NET 67536: close NET 67536: close handle NET 67536: emit close HTTP 67536: CLIENT socket onClose HTTP 67536: removeSocket track.webgains.com:443::::::::::::::::::::: writable: false NET 67536: _onTimeout HTTP 67536: CLIENT socket onTimeout STREAM 67536: readableAddChunk null STREAM 67536: onEofChunk STREAM 67536: emitReadable_ false 0 true STREAM 67536: flow true STREAM 67536: read undefined STREAM 67536: endReadable false STREAM 67536: read 0 STREAM 67536: endReadable false STREAM 67536: endReadableNT false 0 STREAM 67536: endReadableNT true 0 NET 67536: _final: not ended, call shutdown() NET 67536: afterShutdown destroyed=false NET 67536: destroy NET 67536: close NET 67536: close handle NET 67536: emit close HTTP 67536: CLIENT socket onClose
解决方案
1. 调整Agent超时与连接设置
从日志可见,默认Agent的timeout仅5000ms,对响应较慢的电商网站来说过短。同时部分网站对HTTP长连接支持不佳,可关闭keepAlive:
const fetch = require('node-fetch'); const https = require('https'); // 创建自定义Agent const customAgent = new https.Agent({ timeout: 10000, // 延长超时到10秒 keepAlive: false, // 关闭长连接 family: 4 // 强制使用IPv4,避免DNS解析到IPv6导致的连接问题 });
2. 修正请求头规范
GET请求不需要Content-Type头,添加该头可能被网站判定为异常请求,直接移除:
async function fetchDhgate() { try { const res = await fetch('https://www.dhgate.com', { method: 'GET', headers: { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.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.98', 'Accept-Encoding': 'gzip, deflate, br', 'Connection': 'close' // 对应关闭keep-alive }, agent: customAgent, timeout: 10000 // 全局请求超时 }); console.log('请求成功,状态码:', res.status); } catch (err) { console.error('请求失败:', err.message); } } fetchDhgate();
3. 强制指定HTTP/1.1版本
确保node-fetch使用HTTP/1.1而非尝试HTTP/2,在Agent中设置maxVersion:
const customAgent = new https.Agent({ // 其他配置... maxVersion: 'http1.1' });
4. 检查TLS版本兼容性
部分老电商网站对TLS 1.3支持不佳,可强制使用TLS 1.2:
const customAgent = new https.Agent({ // 其他配置... minVersion: 'TLSv1.2', maxVersion: 'TLSv1.2' });
内容的提问来源于stack exchange,提问作者Maxim Vershinin
相关产品推荐
相关产品推荐

