欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > 在 Node.js 中使用 axios 配置代理并实现图片并发下载

在 Node.js 中使用 axios 配置代理并实现图片并发下载

2024/11/30 8:54:01 来源:https://blog.csdn.net/qq_45897239/article/details/140469398  浏览:    关键词:在 Node.js 中使用 axios 配置代理并实现图片并发下载

文章目录

      • 一、创建 Axios 实例
      • 二、图片并发下载
      • 三、参考资料

一、创建 Axios 实例

可以创建一个 axiosConfig.ts 文件用于创建和更新相关实例:

// server/utils/axiosConfig.ts
const axios = require("axios");
const { HttpsProxyAgent } = require('https-proxy-agent');// axios 实例
let axiosInstance = null;// 代理表单(可以从数据库读取相关配置)
let proxyParams = { state: true, host: "127.0.0.1", port: 10809, protocol: "http", username: "", password: ""
};// 创建 axios 实例 
const createAxiosInstance = () =>  {// 判断是否开启代理const useProxy = proxyParams['state'] == true;let axiosConfig = {timeout: 5000};// 启用代理服务if (useProxy && proxyParams) {const agent = new HttpsProxyAgent({host: proxyParams.host,port: proxyParams.port,protocol: proxyParams.protocol,});axiosConfig['httpsAgent'] = agent;}// 代理服务器 用户名、密码if (useProxy && proxyParams['username'] && proxyParams['password']) {axiosConfig['auth'] = {username: proxyParams['username'],password: proxyParams['password']};}axiosInstance = axios.create(axiosConfig);
}// 获取 Axios 实例
const getAxiosInstance = () => {if (!axiosInstance) {createAxiosInstance();}return axiosInstance;
}// 更新 Axios 实例
const updateAxiosInstance = () => {createAxiosInstance();
}module.exports = {getAxiosInstance,updateAxiosInstance
};

代理相关配置可以以字符串的方式先存储在数据库中,再根据需要读取和修改以实现动态更新代理配置:

const { getSettingCache } = require("../db/SettingManager.ts");const createAxiosInstance = () => {// 获取配置信息const settingCache = getSettingCache();// 判断是否开启代理const proxyParams = settingCache["proxy"] ? JSON.parse(settingCache["proxy"]) : null;// {//   proxy: '{"state":true,"host":"127.0.0.1","port":10809,"protocol":"http","username":"","password":""}',// }
}

二、图片并发下载

此处使用 p-limit 来控制并发数量:

yarn add p-limit

创建一个 downloadImages.ts 文件用来处理图片下载相关方法:

// server/utils/downloadImages.ts
const { getAxiosInstance } = require('../utils/axiosConfig.ts');
const path = require("path");
const fs = require("fs");const downloadImagesByUrls = async (imageUrls, savePath) => {// 为避免出现循环导入,此处使用动态导入const pLimit = (await import('p-limit')).default;// 提取 url 中的文件名 例:xxx.jpgconst filenames = imageUrls.map((url) => path.basename(url));// 判断是否存在目标文件夹,不存在则创建if (!fs.existsSync(savePath)) {fs.mkdirSync(savePath, { recursive: true });}// 下载单个图片的函数const downloadImage = async (url, filename) => {// 拼接文件路径const fullPath = path.join(savePath, filename);try {// 获取 axios 实例const axiosInstance = await getAxiosInstance();const response = await axiosInstance({method: "get",url: url,responseType: "stream",});const writer = await fs.createWriteStream(fullPath);// 用Promise包装stream完成事件return new Promise((resolve, reject) => {response.data.pipe(writer);writer.on("finish", () => resolve({ filename, success: true }));writer.on("error", (err) => reject({ filename, success: false, error: err.message }));response.data.on("error", (err) => reject({ filename, success: false, error: err.message }));});} catch (error) {return { filename, success: false, error: error.message };}};// 并发控制const limit = pLimit(5);// 创建下载任务const tasks = imageUrls.map((url, index) => limit(() => downloadImage(url, filenames[index])));// 执行下载任务并等待所有任务完成const results = await Promise.all(tasks);return results;
};module.exports = {downloadImagesByUrls,
};

代码说明: 该方法可直接复制使用,需要传递两个参数,imageUrls 参数为需要下载的图片列表,是一个存储了图片下载链接的数组,例:['http://xxx','http://xxx'],第二个参数是 savePath ,即文件保存路径,例:D:/Desktop,函数会提取文件名称进行路径的拼接,如果路径不存在则会自动创建。

三、参考资料

  • https://www.npmjs.com/package/p-limit
  • https://www.bright.cn/blog/how-tos/axios-proxy
  • https://www.jianshu.com/p/8021d8851775

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com