Node.js使用request模块下载文件时因ECONNRESET请求中止问题
解决Node.js request模块下载文件时的ECONNRESET异常
ECONNRESET错误表示连接被对方重置,通常是远程服务器、代理或网络设备在数据传输完成前主动关闭了连接,可能由网络波动、服务器超时、重定向配置错误等原因引发。结合你的代码,下面是具体的修复方案:
代码中的问题排查
- 拼写错误:
options里的redirct应为redirect,错误的配置会导致重定向处理失效,可能触发连接异常。 - 错误处理漏洞:
pipe后的error事件回调中,error变量未定义,无法捕获具体错误信息。 - 缺乏重试机制:临时网络波动可能导致单次请求失败,没有重试会直接终止下载。
- request模块已废弃:request库自2020年起停止维护,存在潜在bug和安全风险,建议替换为axios或node-fetch。
修复方案
方案1:修复现有request代码
const fs = require('fs'); const request = require('request'); const { promisify } = require('util'); const requestPromise = promisify(request); async function downloadAttachment(url, filename, retryCount = 3) { const username = 'arjunsingh@opkey.com'; const password = 'FfGF0AE55KddipvV4n-7VYvoK8xdGFoDSFsuANd_jkHPyxTwHP_6Q3Iti1mzXMfnEOkYdpduq2izwfIQ0_YSEQigY5m4EJoSJxxVXciU-wOgnywAEYeIb0cUmaFtXLBo37HqH0ncJfXtkseRlUclonTkpG7iam26zm569prbAhmCNPkw=91594DA2'; const auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64'); const options = { method: 'GET', encoding: null, url: url, headers: { 'Authorization': auth, }, timeout: 36000000, redirect: 'follow', // 修复拼写错误 maxBodyLength: Infinity, maxRedirects: 500, }; const filePath = 'C://Users//Admin//OneDrive//Desktop//testDownload//' + filename; const fileStream = fs.createWriteStream(filePath); try { const response = await requestPromise(options); // 将响应数据写入文件流 await new Promise((resolve, reject) => { fileStream.write(response.body, (err) => { if (err) reject(err); else { fileStream.end(resolve); } }); }); console.log(`File downloaded and saved as ${filePath}`); } catch (error) { console.log(`请求错误:${error.message},错误码:${error.code}`); // 重试机制:如果还有重试次数,递归调用 if (retryCount > 0) { console.log(`剩余重试次数:${retryCount},正在重试...`); return downloadAttachment(url, filename, retryCount - 1); } // 关闭文件流并抛出错误 fileStream.close(); throw error; } }
方案2:替换为维护中的axios库(推荐)
axios支持Promise API,错误处理更直观,且持续维护:
const fs = require('fs'); const axios = require('axios'); async function downloadAttachment(url, filename, retryCount = 3) { const username = 'arjunsingh@opkey.com'; const password = 'FfGF0AE55KddipvV4n-7VYvoK8xdGFoDSFsuANd_jkHPyxTwHP_6Q3Iti1mzXMfnEOkYdpduq2izwfIQ0_YSEQigY5m4EJoSJxxVXciU-wOgnywAEYeIb0cUmaFtXLBo37HqH0ncJfXtkseRlUclonTkpG7iam26zm569prbAhmCNPkw=91594DA2'; const filePath = 'C://Users//Admin//OneDrive//Desktop//testDownload//' + filename; const fileStream = fs.createWriteStream(filePath); try { const response = await axios({ method: 'GET', url: url, responseType: 'stream', auth: { username: username, password: password, }, timeout: 36000000, maxRedirects: 500, }); // 管道传输并处理完成/错误事件 await new Promise((resolve, reject) => { response.data.pipe(fileStream); response.data.on('end', resolve); response.data.on('error', reject); fileStream.on('error', reject); }); console.log(`File downloaded and saved as ${filePath}`); } catch (error) { console.log(`下载错误:${error.message},错误码:${error.code}`); if (retryCount > 0) { console.log(`剩余重试次数:${retryCount},正在重试...`); fileStream.close(); return downloadAttachment(url, filename, retryCount - 1); } fileStream.close(); throw error; } }
额外建议
- 检查目标服务器的超时设置:如果服务器端有较短的连接超时,即使客户端设置长超时也会被重置。
- 避免写入OneDrive目录:OneDrive的实时同步可能锁定文件,导致写入失败,建议先下载到本地普通目录,再手动同步。
- 监控网络状态:如果是频繁出现的ECONNRESET,排查本地网络或代理是否存在不稳定情况。
内容的提问来源于stack exchange,提问作者arjun singh
相关产品推荐
相关产品推荐

