outboundAxiosConfig.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. /**
  2. * 统一创建 HTTPS 出站代理 Agent,兼容 https-proxy-agent 各版本的导出方式。
  3. */
  4. function resolveHttpsProxyAgentClass() {
  5. const mod = require('https-proxy-agent')
  6. const AgentClass = mod.HttpsProxyAgent || mod.default || mod
  7. if (typeof AgentClass !== 'function') {
  8. throw new Error('https-proxy-agent 未正确安装或导出格式不兼容')
  9. }
  10. return AgentClass
  11. }
  12. function createHttpsProxyAgent(proxyUrl) {
  13. const HttpsProxyAgent = resolveHttpsProxyAgentClass()
  14. const rejectUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED !== '0'
  15. return new HttpsProxyAgent(proxyUrl, { rejectUnauthorized })
  16. }
  17. /**
  18. * Axios 对「HTTPS 目标 + 内置 proxy」在部分 Node 版本下会报 ERR_INVALID_PROTOCOL,
  19. * 改用 HttpsProxyAgent 走 CONNECT 隧道,并显式 proxy: false。
  20. */
  21. function buildAxiosOutboundConfig(fragment) {
  22. if (!fragment || fragment.proxy === false || !fragment.proxy) {
  23. return { proxy: false }
  24. }
  25. const { host, port, auth } = fragment.proxy
  26. let userPart = ''
  27. if (auth && String(auth.username || '').length > 0) {
  28. const u = encodeURIComponent(auth.username)
  29. const p = encodeURIComponent(auth.password != null ? String(auth.password) : '')
  30. userPart = `${u}:${p}@`
  31. }
  32. const proxyUrl = `http://${userPart}${host}:${port}`
  33. return {
  34. proxy: false,
  35. httpsAgent: createHttpsProxyAgent(proxyUrl)
  36. }
  37. }
  38. module.exports = {
  39. createHttpsProxyAgent,
  40. buildAxiosOutboundConfig
  41. }