Node.js中使用Axios下载图片遇ETIMEDOUT错误求助
解决Node.js下载Medium图片时的ETIMEDOUT问题
问题重现
使用Axios下载Medium图片时触发ETIMEDOUT错误:
code: 'ETIMEDOUT', host: 'miro.medium.com', hostname: 'miro.medium.com', method: 'GET', path: '/v2/resize:fit:1200/1*zPt6so-N8gphr7Kyw6OA1w.jpeg', protocol: 'https:', url: 'https://miro.medium.com/v2/resize:fit:1200/1*zPt6so-N8gphr7Kyw6OA1w.jpeg'
已尝试解码URL、添加User-Agent、更换SuperAgent等第三方下载包,均未解决。
可行解决方案
1. 保留原始编码URL,不要解码
你的代码中对URL做了decodeURIComponent,但1%2A是*的合法URL编码,服务器可能依赖编码后的路径做路由。解码后的*可能导致服务器无法正确识别资源路径,直接使用原始URL即可:
let inputImageUrl = "https://miro.medium.com/v2/resize:fit:1200/1%2AzPt6so-N8gphr7Kyw6OA1w.jpeg"; // 移除decodeURIComponent步骤 const userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36"; axios.get(inputImageUrl, { headers: { "User-Agent": userAgent }, responseType: "stream", timeout: 30000 // 延长超时到30秒 }) .then((response) => { // 处理流,比如写入文件 const fs = require('fs'); response.data.pipe(fs.createWriteStream('downloaded-image.jpeg')); }) .catch((err) => { console.error(err); });
2. 补充完整浏览器请求头
Medium的CDN可能会检查请求的完整性,仅加User-Agent不够,补充Referer、Accept等头模拟真实浏览器请求:
const headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36", "Accept": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "zh-CN,zh;q=0.9", "Referer": "https://medium.com/" // 关键:添加来源页 }; axios.get(inputImageUrl, { headers, responseType: "stream", timeout: 30000 }) // ...后续处理
3. 检查网络与代理配置
如果是公司/校园网络,大概率是代理拦截了请求,需要在Axios中配置代理:
axios.get(inputImageUrl, { headers, responseType: "stream", timeout: 30000, proxy: { host: "your-proxy-address", port: 8080, // 替换成你的代理端口 // 如果代理需要认证 auth: { username: "proxy-username", password: "proxy-password" } } }) // ...后续处理
4. 用原生HTTPS模块测试排除第三方包问题
第三方包可能有隐藏的配置问题,用Node.js原生模块测试:
const https = require('https'); const fs = require('fs'); const inputImageUrl = "https://miro.medium.com/v2/resize:fit:1200/1%2AzPt6so-N8gphr7Kyw6OA1w.jpeg"; const headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36", "Referer": "https://medium.com/" }; const request = https.get(inputImageUrl, { headers, timeout: 30000 }, (res) => { if (res.statusCode === 200) { res.pipe(fs.createWriteStream('native-download.jpeg')) .on('finish', () => console.log('下载完成')); } else { console.error(`请求失败,状态码:${res.statusCode}`); } }); request.on('timeout', () => { console.error('请求超时'); request.destroy(); }); request.on('error', (err) => console.error(err));
排查思路
- 先用
curl命令测试网络连通性:
如果curl能成功,说明问题出在代码配置;如果curl也超时,就是网络/服务器拦截问题。curl -v "https://miro.medium.com/v2/resize:fit:1200/1%2AzPt6so-N8gphr7Kyw6OA1w.jpeg" -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36" -H "Referer: https://medium.com/"
内容的提问来源于stack exchange,提问作者Jude Sebastian Xavier
相关产品推荐
相关产品推荐

