在 Node.js 中,Axios 访问 HTTP 或 HTTPS 目标时,可以用 proxy 指定 HTTP/HTTPS 代理;使用 SOCKS5 时,通常把 SocksProxyAgent 交给 httpAgent 和 httpsAgent。如果代码里没有显式配置代理,请求却仍经过代理,还要检查 HTTP_PROXY、HTTPS_PROXY 等环境变量。本文只解决 Axios 的配置、认证、出口验证和连接失败排查,不展开代理协议原理。

你要做什么优先使用关键设置
单次请求使用 HTTP/HTTPS 代理Axios proxyprotocol、host、port
多个请求复用同一代理配置axios.create()实例级 proxy
使用 SOCKS5 代理SocksProxyAgenthttpAgent / httpsAgent
服务器或容器统一指定代理环境变量HTTP_PROXY / HTTPS_PROXY
让指定目标不走环境代理NO_PROXY目标 Host 匹配规则
明确不使用 Axios 的环境代理proxy: false同时核对是否存在自定义 Agent

先在项目里安装 Axios;SOCKS5 章节还需要安装 socks-proxy-agent。下文 JavaScript 示例使用 Node.js ESM,可保存为 .mjs 文件运行,或在项目中启用 ESM。

npm install axios
npm install socks-proxy-agent

一、Axios 代理有哪些配置方式?

proxy、Agent 和环境变量不是三种写法不同的同一功能。选哪一种,取决于代理协议以及配置应该放在单次请求、Axios 实例,还是整个运行环境。

HTTP/HTTPS 代理:先看 proxy

代理服务商给的是 HTTP 或支持 TLS 的 HTTPS 代理端点时,可以在 Axios 请求配置中填写 proxy.protocol、proxy.host 和 proxy.port。它们描述的是客户端连接的代理服务器,不是目标 API 的地址。Axios 官方把这一项标为 Node.js 配置,并说明它也能读取常见代理环境变量,详见 Axios Request config。

SOCKS5:使用 Agent

Axios 的普通 proxy 对象不应被当成 SOCKS5 配置入口。SOCKS5 请求通常由 socks-proxy-agent 建立连接,再把 Agent 交给 Axios。自定义 Agent 也可能用于连接池或证书等其他连接行为,但本文只讨论 SOCKS5。

统一出口:使用环境变量

服务器、容器或 CI 中的多个请求需要共用代理时,可以让运行环境提供 HTTP_PROXY、HTTPS_PROXY 与 NO_PROXY。这省去了每个请求重复写 Host 和 Port,但也会产生“代码没写代理却仍走代理”的排查问题。

以下示例以 Node.js 的 Axios HTTP adapter 为范围。浏览器端 Axios 不能直接照搬 httpAgent、httpsAgent 或 Node.js 环境变量的配置;浏览器请求是否走代理取决于浏览器和所在系统的网络设置。

Axios代理配置方式:proxy、SocksProxyAgent和环境变量
Axios 代理配置方式:HTTP/HTTPS 使用 proxy,SOCKS5 使用 Agent;多请求复用可用 axios.create(),统一运行环境可使用代理环境变量。

二、Axios 怎么配置 HTTP / HTTPS 代理?

最小的 HTTP 代理请求

下面用 HTTP 代理请求一个 HTTPS 目标。把示例 Host 和 Port 换成代理服务商实际提供的端点;无账号密码时可先用这段确认连通性。

import axios from 'axios';

const response = await axios.get('https://api.ipify.org?format=json', {
  proxy: {
    protocol: 'http',
    host: 'proxy.example.com',
    port: 7778
  },
  timeout: 15000
});

console.log(response.data);

目标 URL 是 https://,并不意味着代理协议也要改成 https。只有代理服务商明确提供支持 TLS 的 HTTPS 代理端点时,proxy.protocol 才应填写 https。两种协议的边界可参考站内的 HTTP、HTTPS 与 SOCKS5 代理区别。

字段示例容易出错的地方
protocolhttp根据目标 API 的 https:// 擅自改成 https
hostproxy.example.com把 http:// 或整串账密连接 URL 塞进 Host
port7778凭端口号猜协议,或把旧端口与新 Host 混用

多个请求复用同一代理

如果同一组业务请求使用同一代理配置,可以创建 Axios 实例,而不必每次重写代理对象。请求级配置仍可覆盖实例默认值;这一点见 Axios 的实例文档。

const client = axios.create({
  proxy: {
    protocol: 'http',
    host: 'proxy.example.com',
    port: 7778
  },
  timeout: 15000
});

const first = await client.get('https://api.example.com/items');
const second = await client.get('https://api.example.com/status');

axios.create() 复用的是配置,不等于固定出口 IP:最终出口仍取决于代理产品的固定、会话或轮换规则。示例中的目标 API 只是占位地址,实际运行时要换成可访问的业务接口。

三、Axios 代理账号密码怎么填写?

proxy.auth 认证代理服务器

HTTP/HTTPS 代理需要用户名和密码时,把它们放进 proxy.auth,而不是请求顶层的 auth。下面在第二节的 HTTP 代理配置基础上加入 auth 字段:

proxy: {
  protocol: 'http',
  host: 'proxy.example.com',
  port: 7778,
  auth: {
    username: process.env.PROXY_USER,
    password: process.env.PROXY_PASS
  }
}

实际使用前确认两个环境变量已有值,不要把真实密码写进文章示例、公开仓库或错误日志。如果服务商要求来源 IP 白名单,账号密码与白名单是不同的认证条件,具体以服务商给出的规则为准。

代理认证与目标 API 认证不是一回事

Axios 写法认证对象常见用途
proxy.auth代理服务器代理的 Basic 认证用户名和密码
headers.Authorization目标 APIBearer Token 等接口凭证
请求顶层的 auth目标服务器目标 API 的 HTTP Basic Auth

如果把代理账号填进顶层 auth,Axios 会把它当作目标服务器的 HTTP Basic 凭证。Axios 官方也提醒,顶层 auth 会设置或覆盖目标请求的 Authorization Header。目标 API 使用 Bearer Token 时,应按 API 文档填写请求 Header,而不是混进 proxy.auth。

出现 407 时先查什么?

407 Proxy Authentication Required 表示代理要求认证,而当前请求没有提供可接受的代理凭证。优先核对代理 Username、Password、来源 IP 白名单、服务商要求的用户名参数和认证方式。这里不重写完整故障树;如果最小请求仍返回 407,可继续看 407 代理认证专项排查。

四、Axios 怎么使用 SOCKS5 代理?

不要把 socks5 直接填入 Axios 的 proxy.protocol,期待它像 HTTP 代理一样工作。socks-proxy-agent 提供面向 HTTP/HTTPS 请求的 SOCKS Agent;创建后交给 Axios 的 httpAgent 和 httpsAgent。这两个字段分别对应 HTTP 与 HTTPS 目标请求,不表示代理端点本身有两种协议。

前面已安装 socks-proxy-agent。下面的示例从环境变量读取 SOCKS5 账号密码,并只对 URL 中的凭证字段做编码;如果代理不需要账密,Agent URL 可以直接写为 socks5://proxy.example.com:1080。

import axios from 'axios';
import { SocksProxyAgent } from 'socks-proxy-agent';

const user = process.env.PROXY_USER;
const pass = process.env.PROXY_PASS;
if (!user || !pass) throw new Error('缺少代理认证环境变量');

const agent = new SocksProxyAgent(
  `socks5://${encodeURIComponent(user)}:${encodeURIComponent(pass)}@proxy.example.com:1080`
);

const response = await axios.get('https://api.ipify.org?format=json', {
  httpAgent: agent,
  httpsAgent: agent,
  proxy: false,
  timeout: 15000
});

console.log(response.data);
Axios HTTP代理与SOCKS5 Agent请求链路对比
HTTP 代理通过 Axios proxy 配置;SOCKS5 通过 SocksProxyAgent 连接。若要避免 Axios 同时读取自身代理配置或环境代理,可配合 proxy: false。

这里的 proxy: false 用来阻止 Axios 再通过自身的 proxy 配置或环境代理解析改写这次请求;它不会关闭你显式传入的 SocksProxyAgent。如果把 Agent 和另一个 proxy: {...} 对象混在一起,很难判断实际使用的是哪条代理链路。Agent 的用法可参考 socks-proxy-agent 官方示例。

这里的 URL 是代理连接地址,不是目标网站地址。用户名或密码包含 @、:、# 等特殊字符时,不要直接拼进 URL;上例用 encodeURIComponent() 只处理两个凭证字段,避免破坏 URL 结构。

五、HTTP_PROXY、HTTPS_PROXY 和 NO_PROXY 怎么配?

如果代理配置应随服务器、容器或 CI 环境统一管理,可以设置代理环境变量。以下是 Bash/zsh 示例;变量值要以实际代理端点为准,示例中的凭证不能直接用于生产环境。

export HTTP_PROXY="http://USERNAME:PASSWORD@proxy.example.com:7778"
export HTTPS_PROXY="http://USERNAME:PASSWORD@proxy.example.com:7778"
export NO_PROXY="localhost,127.0.0.1,internal.example.com"

如果 Username 或 Password 包含 @、:、#、% 等 URL 特殊字符,应只对凭证字段做 URL 编码,再拼入代理 URL;不要对整条代理 URL 统一编码。

HTTPS_PROXY 中的 HTTPS 指要访问的目标 URL 类型;变量值仍可以是 http:// 开头的 HTTP 代理端点。NO_PROXY 用于列出不通过环境代理访问的目标 Host。不同 Node.js 版本、Agent 和 Axios adapter 对环境代理的处理可能不同;排查时以运行中的进程实际环境与请求出口为准,不要只看本地终端。

代码没写代理,为什么 Axios 仍走代理?

常见原因是当前进程继承了 HTTP_PROXY 或 HTTPS_PROXY,或容器、CI、启动脚本注入了变量。检查当前进程的变量名和目标 URL 协议,同时确认请求没有使用另一个自定义 Agent。若这次请求明确不应使用 Axios 的环境代理,可在请求配置中写 proxy: false;但若显式传入了代理 Agent,仍要单独移除或更换该 Agent。

不要把带真实用户名和密码的环境变量值直接粘贴到工单、聊天或构建日志里。团队环境最好通过受控的 Secret 管理方式注入凭证,并在诊断输出中脱敏。

六、怎么验证 Axios 请求真的经过代理?

用同一台运行 Node.js 的机器、同一个 IP 查询接口,做直连与代理的 A/B 对照。先记录不使用 Axios 代理的结果,再只增加代理配置重试。下面示例适用于用户名密码认证:运行前设置 PROXY_USER 和 PROXY_PASS;纯 IP 白名单模式可删去 auth 字段。不能把“请求成功返回 200”当作代理已经生效的证据。

import axios from 'axios';

const url = 'https://api.ipify.org?format=json';
const direct = await axios.get(url, {
  proxy: false,
  timeout: 15000
});
const viaProxy = await axios.get(url, {
  proxy: {
    protocol: 'http',
    host: 'proxy.example.com',
    port: 7778,
    auth: {
      username: process.env.PROXY_USER,
      password: process.env.PROXY_PASS
    }
  },
  timeout: 15000
});

console.log({ direct: direct.data.ip, proxy: viaProxy.data.ip });
Axios直连与代理出口IP的A/B验证示意
出口验证示意图:从同一进程、同一接口比较 Direct 与 Via Axios Proxy。图中 IP 为文档示例地址,不代表真实测试结果。

这段对照代码使用的是 HTTP 代理;如果测 SOCKS5,把第二次请求替换为第四节的 Agent 配置。direct 显式设置了 proxy: false,但还应确认这个请求没有继承自定义代理 Agent,也没有被进程外的系统级转发接管,否则所谓“直连”基线仍可能不是直连。

正常使用独立代理出口时,两次结果通常不同。如果代理配置指定了国家或地区,再用同一个 GEO 查询来源核对地理信息;“出口发生变化”和“地区符合预期”是两项不同的验收。还分不清本地 IP、公网 IP 与代理出口时,可参考 本地 IP 与公网出口的判断方法。

固定代理、Sticky Session 和轮换代理怎么看结果?

代理类型重复请求时看什么不要误判为
固定代理多次请求是否保持同一出口只成功一次就算通过
Sticky Session同一 Session 在约定时长内是否保持出口换了 Session 还要求地址不变
轮换代理是否按服务商声明的触发条件变化每次请求都必须换 IP

这里只验证出口行为,不展开代理池和轮换策略。

七、Axios 代理连接失败怎么排查?

先记录错误代码、请求目标、实际使用的代理 Host/Port 与运行环境,再逐项排查。相同的错误代码不一定都由代理引起;尤其是拒绝连接或超时,要结合报错指向的地址判断失败发生在代理连接还是目标请求。

错误或现象优先检查下一步
ECONNREFUSED报错中的 Host/Port、代理服务是否在监听确认拒绝连接的是代理还是目标 API
ECONNABORTED / ETIMEDOUTAxios timeout、网络、代理端点与目标响应分别测试连代理与经代理访问目标
407 Proxy Authentication Requiredproxy.auth、白名单、用户名参数转入 407 专项排查,不靠重试掩盖认证错误
请求成功但出口 IP 没变化实际代码分支、proxy、环境变量、Agent从同一进程运行第六节 A/B 测试
SOCKS5 请求没有按预期走代理SocksProxyAgent、两个 Agent 字段、proxy: false不要再混用另一个 proxy 对象
HTTPS 或证书错误目标站证书、代理端点协议是否填写正确、CA / TLS 链路先辨认出错的一跳,不长期关闭证书验证
部分目标不走环境代理NO_PROXY 与目标 Host检查实际匹配结果,不把排除列表当安全边界
代码没配代理却仍走代理HTTP_PROXY、HTTPS_PROXY、容器和 CI 配置检查运行进程实际继承的变量

加了 Agent,为什么 Axios 还是走错代理?

确认同一次请求没有同时保留另一个 proxy: {...};检查项目是否通过实例默认值或拦截器又设置了代理;再查看 HTTP_PROXY、HTTPS_PROXY 是否存在。使用 SOCKS5 Agent 时,把请求级 proxy: false 与 Agent 放在同一处配置,更容易判断 Axios 本身不会再选另一个环境代理。

设置 proxy: false 后正常了,说明什么?

这通常提示此前 Axios 的代理配置或环境代理参与了请求路径,但不能仅凭这一项就证明是哪一个变量造成问题。对比修改前后的出口 IP,再检查实例配置、环境变量、Agent 和目标 URL。若要定位确切原因,一次只移除一层配置,不要同时改代理地址、凭证和超时。

八、Axios 代理常见问题

1. 浏览器端 Axios 可以直接用 proxy 或 SocksProxyAgent 吗?

不能照搬本文的 Node.js 写法。Axios 文档将 proxy 标为 Node.js 配置,httpAgent 和 httpsAgent 也用于 Node.js。浏览器端请求走不走代理,通常由浏览器和系统网络设置决定。

2. Axios 配 HTTP 代理与 SOCKS5 代理,写法为什么不同?

HTTP/HTTPS 代理可以使用 Axios 的 proxy 对象;SOCKS5 通常由专门的 Agent 建立代理连接,再通过 httpAgent、httpsAgent 交给 Axios。不要只替换 proxy.protocol 的字符串。

3. proxy 和 httpAgent / httpsAgent 能一起设置吗?

它们可以在配置对象里同时出现,但不应无目的地叠加两套代理链路。使用 SOCKS5 Agent 时,本文示例通过 proxy: false 关闭 Axios 自身的代理解析,让 Agent 负责连接;如果是其他自定义 Agent,应按它的实际功能分别验证。

4. Axios 为什么会读取 HTTP_PROXY?

在 Node.js 环境中,Axios 支持通过代理环境变量选择出口。代码里没有显式 proxy,并不代表运行进程没有代理设置。排查时要查看服务器、容器、CI 和启动脚本实际注入的变量。

5. Axios 返回 407 应该改目标 API 的 Token 吗?

通常不该。407 对应代理认证要求,应先核对 proxy.auth、来源 IP 白名单和服务商的用户名参数;目标 API 的 Token 属于另一层认证。确认代理认证后,再检查目标服务自己的 401 或 403。

最终验收至少确认三项:Axios 实际连接的代理端点、同一进程里的直连与代理出口对比,以及重复请求时出口是否符合产品规则。代码执行成功,只能说明请求完成,不能单独证明代理配置正确。