Axios 代理不生效:16 个原因与修复(实测)

Node.js 中 Axios 请求绕过代理或经代理失败?按症状列出 16 个原因和实测修复:1.21 中 proxy: false 绕过 proxyEnv agent、HTTP/2 与 fetch 适配器直连、1.16.1 之前不发 CONNECT、407 与密码编码、NO_PROXY 匹配、重定向、SOCKS5。

本页内容

Node.js 中的 Axios 请求绕过代理,或者在经过代理时失败,原因就在下面这 16 个之中,而且大多数与 Axios 版本有关。Axios 1.21.0 和 1.21.1 在设置了 proxy: false 时会忽略带 proxyEnv 的 agent。httpVersion: 2 和 fetch 适配器在所有支持它们的版本上都是直连。1.16.1 之前的版本从不为 https:// 地址建立 CONNECT 隧道。每个原因都附有我们记录的输出和我们实际运行过的修复方法。

测试环境:Node.js 24.22.2 和 26.13.0,Axios 1.12.2、1.19.0、1.20.0、1.21.0 和 1.21.1,另加 1.13.6、1.15.0、1.16.0、1.16.1 和 1.18.1 用来定位行为变化的版本,https-proxy-agent 9.1.0 和 socks-proxy-agent 10.1.0,macOS 26.5.1 arm64,2026 年 11 月 11 日。实验环境是 127.0.0.1 上一个带日志的代理和一个 HTTPS 目标。“被绕过”指目标作出了响应,而代理什么也没有记录。脚本、结果表和全部 1290 条记录都在实验文件夹中(英文)。第一次配置代理,请先看 Axios 代理设置;本页针对的是配置好了却表现不对的情况。

快速检查:请求是否经过代理?

js
import axios from 'axios';

// Use the same client and options as the code you are debugging.
const res = await axios.get('https://api.ipify.org?format=json', {
  proxy: { protocol: 'http', host: 'proxy.example', port: 8080 },
});
console.log(res.data);

用出问题的那段代码的选项运行一次,再完全不带代理运行一次。如果两次输出的 IP 相同,说明请求绕过了代理。200 什么也证明不了:本页的每一次绕过都返回了 200。如果能看到代理自己的日志,先看那里。在实验中,每个经过代理的 https:// 请求都留下一行 CONNECT,被绕过的请求一行也没有。

找到你的症状

你看到的现象前往
状态 200,但 IP 是你自己的,代理没有任何日志请求绕过代理
400、socket hang up、wrong version number、ENOTFOUND undefined,或请求一直不返回经 HTTP 代理访问 HTTPS 失败
Request failed with status code 407407 与认证错误
设置了 HTTPS_PROXY 却被忽略,或不该跳过代理的主机被跳过环境变量与 NO_PROXY
第一个请求走代理,重定向却没有重定向离开代理
protocol mismatch,或 SOCKS 代理无法解析主机名SOCKS5 代理

请求绕过代理,且没有任何报错

1. proxy: false 与带 proxyEnv 的 agent 同时使用(Axios 1.21.0 及之后)

js
import https from 'node:https';
import axios from 'axios';

const agent = new https.Agent({ proxyEnv: { https_proxy: 'http://proxy.example:8080' } });
const res = await axios.get('https://example.com/', { proxy: false, httpsAgent: agent });
console.log(res.status);

在 Axios 1.20.0 上,这个请求经过了实验代理。在 1.21.0 上,同一个脚本输出:

code
200
# proxy log: (nothing)
# target log: GET /ip HTTP/1.1 direct

从 1.21.0 起,proxy: false 的含义是“直接连接”,即使 agent 自带代理设置也一样:Axios 会把 agent 换成一个不带 proxyEnv 的副本(#11402,2026 年 11 月 5 日关闭;改动来自 PR #11242,提交 2498c23)。在实验中,Node 自带的开关也是同样的结果:NODE_USE_ENV_PROXY=1 或 --use-env-proxy 加上 proxy: false,在 1.20.0 及之前走代理,在 1.21.0 和 1.21.1 上直连。

修复:从使用这类 agent 的请求中去掉 proxy: false。#11402 的报告者确认了这一点,在实验中去掉该选项的脚本在全部十个版本上都经过了代理。agent 带有 proxyEnv 时,Axios 会把环境代理交给它处理(请求配置文档)。与 HttpsProxyAgent 这类第三方 agent 搭配时,请保留 proxy: false:这一组合在所有版本上都有效(原因 5)。

2. httpVersion: 2

js
import axios from 'axios';

// HTTPS_PROXY=http://proxy.example:8080 is set in the environment.
const res = await axios.get('https://example.com/', { httpVersion: 2 });
console.log(res.status);

在 Axios 1.21.1 上:

code
200
# proxy log: (nothing)
# target log: GET /ip HTTP/2.0 direct
Axiosproxy 对象HTTPS_PROXYproxy: false + HttpsProxyAgent
1.13.6、1.15.0、1.16.0ERR_HTTP2_ERRORERR_HTTP2_ERROR被绕过,无报错
1.16.1、1.18.1、1.19.0被绕过,无报错被绕过,无报错被绕过,无报错
1.20.0、1.21.0、1.21.1ERR_NOT_SUPPORT被绕过,无报错被绕过,无报错

Axios 1.12.2 不支持 HTTP/2,忽略了这个选项。安全公告 GHSA-3pq3-5fj3-cg6v(CVE-2026-101898,GitLab 条目)覆盖 1.13.0 至 1.20.0 之前的版本:HTTP/2 路径自行建立连接,丢掉了代理。实验在 1.16.1 到 1.19.0 上复现了无声的绕过。在 1.13.6、1.15.0 和 1.16.0 上,请求向代理发送了 HTTP/2 字节后以 Protocol error 失败,所以在这些版本上失败是看得见的,而不是无声的。

1.20.0 的修复会拒绝显式的 proxy 对象,报错 HTTP/2 requests with a proxy are not supported。它不覆盖环境变量:PR #11141 写明,当代理只来自环境变量或 agent 时,HTTP/2 仍然直连;文档也说 HTTP/2 请求无法走代理。NODE_USE_ENV_PROXY=1 同样是直连。

修复:凡是必须走代理的请求,都去掉 httpVersion: 2。去掉后,同一个请求在 1.16.1 及之后的版本上以 HTTP/1.1 经过了代理。

3. fetch 适配器

使用 adapter: 'fetch' 时,proxy 对象、HTTPS_PROXY 和 httpsAgent 在全部十个版本、两条 Node 版本线上都被无声绕过。文档把 proxy 标为仅限 Node.js,而在实验中只有默认的 HTTP 适配器会读取该选项、代理环境变量或 agent。

修复:去掉 adapter: 'fetch',或者让 Node 为自己的 fetch 走代理:设置 NODE_USE_ENV_PROXY=1 和 HTTPS_PROXY 后,fetch 适配器在 Node 24.22.2 和 26.13.0 上都经过了代理。proxy: false 并不能关掉它。如果报错是 fetch failed,请看修复 Node.js 在代理后的 fetch failed 和 Node.js 26 上的 invalid onError method。

4. agent 放错了选项

只把 HttpsProxyAgent 作为 httpAgent 传入,而地址是 https://:在所有版本上都被无声绕过。Axios 对 http:// 请求使用 httpAgent,对 https:// 请求使用 httpsAgent(README)。

修复:两个选项都设置,像下文 SOCKS 示例那样。

经 HTTP 代理访问 HTTPS 失败

5. 1.16.1 之前的 Axios 不发送 CONNECT

使用 proxy 对象或 HTTPS_PROXY 时,Axios 1.12.2、1.13.6、1.15.0 和 1.16.0 没有向代理请求隧道。实验代理在一个普通请求里收到了完整的 URL:

code
AxiosError: Request failed with status code 400
# exit code: 1
# proxy log: A GET https://target.test:<T>/ip -> 400
# target log: (nothing)

我们的代理用 400 拒绝这种请求。另一个会直接断开连接的实验代理则产生了 socket hang up(ECONNRESET),也就是 #4531 中报告的错误。该 issue 于 2022 年 3 月提交,2025 年 7 月 30 日在一次清理中关闭,当时要求报告者重新测试。#3384 于 2022 年 6 月关闭,描述的是同样的配置,但报的是某个代理特有的握手错误,我们未能复现。

Axios 1.16.1 改变了这一点:按照 PR #10858,Axios 对 HTTPS 目标使用 CONNECT 隧道,而不再把请求的 URL、请求头和请求体以明文转发给代理。从 1.16.1 起,这些用例全部走了隧道。

修复:升级到 1.16.1 或更高版本。如果无法升级,就使用代理 agent,并关闭 Axios 自己的代理处理。这在全部十个版本上都有效,包括 1.12.2:

js
import axios from 'axios';
import { HttpsProxyAgent } from 'https-proxy-agent';

const agent = new HttpsProxyAgent('http://proxy.example:8080');
const res = await axios.get('https://example.com/', {
  proxy: false, // Axios adds no proxy handling of its own
  httpsAgent: agent, // the agent opens the CONNECT tunnel
  signal: AbortSignal.timeout(15000),
});
console.log(res.status);

6. wrong version number:代理的协议写错或漏写

code
write EPROTO <id>:error:0A00010B:SSL routines:tls_validate_record_header:wrong version number:../deps/openssl/openssl/ssl/record/methods/tlsany_meth.c:78:

客户端在用 TLS 与一个只讲明文 HTTP 的代理端口通信。在所有版本上,以下写法都让实验得到了这个错误:proxy 对象中的 protocol: 'https'、HTTPS_PROXY=https://127.0.0.1:8080、完全不带协议的 HTTPS_PROXY=127.0.0.1:8080,以及 new HttpsProxyAgent('https://…')。在 1.16.0 及之前,不带 protocol 的 proxy 对象也以同样方式失败;从 1.16.1 起它可以正常工作。

protocol 和 URL 的协议描述的是到代理的连接,而不是到网站的连接:只有代理本身提供 TLS 时才使用 https(README)。#6198 报告了使用 HttpsProxyAgent 时的这个错误;它在 2025 年 8 月因缺少复现步骤而关闭,而其中的配置换成 http:// 代理地址后在我们的实验中可以正常工作。

修复:对普通的 HTTP 代理,写 protocol: 'http',或在 URL 中写 http://。经代理出现 SSL: wrong version number 讲的是其他客户端中的同一个错误。

7. 代理写成了字符串,或协议写进了 host

  • proxy: 'http://proxy.example:8080'(字符串):从 1.16.1 起是 getaddrinfo ENOTFOUND undefined,此前是 connect ECONNREFUSED ::1:443。
  • proxy: { host: 'http://proxy.example', port: 8080 }:从 1.16.1 起是 Invalid URL(ERR_INVALID_URL),此前是 getaddrinfo ENOTFOUND http://127.0.0.1。

两种写法都没有到达代理。2020 年关闭的 #2072 在浏览器代码中用了第二种写法,而 proxy 选项在浏览器中根本不起作用(文档);我们没有测试浏览器。

修复:传入一个对象,host 写不带协议的主机名,port 写数字或字符串,协议写在 protocol 中。

8. 请求一直不返回

从 Axios 1.16.1 起,使用 proxy 对象或 HTTPS_PROXY 时,如果代理在收到 CONNECT 后关闭连接,或者始终不应答,请求就会一直挂起:15 秒后既没有响应也没有错误,尽管设置了 timeout: 5000。在 1.16.1 之前,同样的用例会以 socket hang up 或 timeout of 5000ms exceeded 被拒绝。使用 proxy: false 加 HttpsProxyAgent 时,连接被关闭会以 Proxy connection ended before receiving CONNECT response 被拒绝,而不应答的代理在全部十个版本上都让请求一直挂起。http:// 地址则正常被拒绝,报 timeout of 5000ms exceeded 或 socket hang up。截至 2026 年 11 月 11 日,我们没有找到关于这个问题的 Axios issue。

修复:给每个走代理的请求单独设置截止时间。signal: AbortSignal.timeout(3000) 让每个挂起的用例在 3 秒后以 canceled(ERR_CANCELED)结束。maxRedirects: 0 也能让 timeout 对内置隧道生效,1.16.0 的发布说明提到过这种情况。

407 与认证错误

密码错误或没有密码时,所有版本返回的结果都一样,无论凭据来自 proxy.auth、HTTPS_PROXY 还是 HttpsProxyAgent 的 URL:Request failed with status code 407,其中 error.code 为 ERR_BAD_REQUEST,error.response.status 为 407。代理记录了一个请求并以 407 应答,目标什么也没有看到。SOCKS5 代理没有状态码:那里密码错误得到的是 Socks5 Authentication failed。

9. 凭据放错了位置

把代理的用户名和密码放在顶层的 auth 选项中,返回了 407,代理日志显示它没有收到任何凭据。顶层的 auth 是给网站用的;代理的凭据要放在 proxy.auth 中(README)。使用 proxy.auth 时,从 1.16.1 起代理对 CONNECT 完成了认证,目标始终没有看到 Proxy-Authorization 请求头,重定向到第二个主机时也一样。

10. 特殊字符的编码方式不对

实验代理期望的密码是 p@ss/w0rd#1:

密码写在哪里写法结果
proxy.auth.password原样经过代理(1.16.1 及之后)
proxy.auth.password百分号编码407:代理收到的是 p%40ss%2Fw0rd%231
HTTPS_PROXY 的 URL原样getaddrinfo ENOTFOUND ss
HTTPS_PROXY 的 URL百分号编码407:代理收到的是 p%40ss%2Fw0rd%231
HttpsProxyAgent 的 URL百分号编码经过代理(所有版本)

原样粘贴时,@ 提前结束了凭据部分,ss 成了主机名。使用百分号编码时,URL 可以解析,但 Axios 把其中的用户名和密码原样取出,不做解码(1.21.1 的 http.js)。因此在测试过的版本上,含保留字符的密码根本无法通过 HTTPS_PROXY 传递。

修复:在 proxy.auth 中不编码地传入,或者在 agent 的 URL 中使用百分号编码。下面两个请求在 1.19.0 到 1.21.1 上都经过了代理:

js
import axios from 'axios';
import { HttpsProxyAgent } from 'https-proxy-agent';

const user = process.env.PROXY_USER;
const pass = process.env.PROXY_PASS;

// In the proxy object: the raw password, not percent-encoded.
const a = await axios.get('https://example.com/', {
  proxy: { protocol: 'http', host: 'proxy.example', port: 8080, auth: { username: user, password: pass } },
});

// In a proxy URL for an agent: percent-encode both parts.
const url = `http://${encodeURIComponent(user)}:${encodeURIComponent(pass)}@proxy.example:8080`;
const b = await axios.get('https://example.com/', { proxy: false, httpsAgent: new HttpsProxyAgent(url) });
console.log(a.status, b.status);

如果凭据正确仍然出现 407,例如由于 IP 白名单或用户名格式,请看修复代理错误 407。

环境变量没有生效,或 NO_PROXY 匹配不对

在实验中,Axios 在全部十个版本上读取的是:https:// 地址读 HTTPS_PROXY 或 https_proxy,http:// 地址读 HTTP_PROXY 或 http_proxy,缺少对应变量时读 ALL_PROXY 或 all_proxy。大小写两种写法都设置时,小写的优先。变量在发出请求时读取,所以在请求前用代码给 process.env.HTTPS_PROXY 赋值是有效的。proxy 对象的优先级高于这些变量和 NO_PROXY。在 1.16.1 之前,变量的读取方式相同,但 https:// 请求随后会像原因 5 那样失败。

11. 变量与 URL 的协议不匹配

只设置 HTTP_PROXY 时,https:// 请求在所有版本上都是直连,没有任何报错。只设置 HTTPS_PROXY 时,http:// 请求也是如此。

修复:两个都设置,通常指向同一个 http:// 代理地址。代理环境变量比较了其他客户端读取它们的方式。

12. 环境中的代理覆盖了你的 agent

设置了 HTTPS_PROXY 时,作为 httpsAgent 传入、且没有 proxy: false 的 HttpsProxyAgent 或 SocksProxyAgent 会被忽略:从 1.16.1 起,请求走的是环境变量中的代理,而不是 agent 的代理。与 agent 同时存在的 proxy 对象也以同样的方式胜出。只要 CI 运行器或容器设置了 HTTPS_PROXY,你的流量就可能走另一个代理,而不是代码中写的那个。

修复:凡是使用第三方代理 agent 的请求,都加上 proxy: false。加上之后,无论环境里有什么,请求在全部十个版本上都走了 agent 的代理。

13. NO_PROXY 在不同版本上匹配结果不同

设置了代理变量,URL 的主机为 target.test 时:

NO_PROXY路由版本
target.test、TARGET.TEST、.test、*.test、*、带 URL 端口的 target.test:PORT直连全部
other.test target.test 或 other.test, target.test直连全部
.target.test、test、get.test、target.test:9999、https://target.test代理全部
target.test,而 URL 写的是带结尾点号的 target.test.1.12.2 和 1.13.6 走代理,1.15.0 起直连在 1.15.0 中修复
127.0.0.0/8,URL 主机为 127.0.0.11.19.0 及之前走代理,1.20.0 起直连在 1.20.0 中修复
localhost,URL 主机为 127.0.0.11.15.0 及之前走代理,1.16.0 起直连在 1.16.0 中变更

结尾点号那一行对应 GHSA-3p68-rc4w-qgx5,在 1.15.0 中修复。CIDR 那一行对应 GHSA-44g4-m2mj-wpvx(CVE-2026-101899),在 1.20.0 中修复;公告列出的受影响版本是 1.15.0 及之后,而在实验中 1.12.2 和 1.13.6 同样忽略了 CIDR 条目。未设置 NO_PROXY 时,发往 localhost 和 127.0.0.1 的请求在所有版本上都走了代理。NO_PROXY 匹配规则实测中有针对其他客户端的同一张矩阵。

重定向离开代理

14. 重定向改变了协议,或跳到了 NO_PROXY 中的主机

实验目标以 302 跳转到第二个主机。

  • 从 http:// 到 https://,只设置了 HTTP_PROXY:第一跳走代理,第二跳直连,所有版本都是如此。使用 proxy: false 且只设置 httpAgent 时也一样。两个 agent 都设置时,或从 1.16.1 起两个变量都设置时,两跳都走代理。
  • 从 https:// 到另一个主机的 https://:使用 proxy 对象、HTTPS_PROXY 或 agent 时,从 1.16.1 起两跳都走代理。启用代理认证时,两个 CONNECT 请求都带有凭据。
  • 重定向到 NO_PROXY 中列出的主机:在 1.21.0 和 1.21.1 上,第二跳直连。在 1.16.1 到 1.20.0 上,它仍然走代理。使用显式的 proxy 对象时,从 1.16.1 起两跳都走代理。

修复:两个变量或两个 agent 都设置。如果重定向绝不能离开代理,就使用 proxy 对象,或一对 agent 加 proxy: false,并且不要把那个主机写进 NO_PROXY。

SOCKS5 代理

15. 在 proxy 选项或 HTTPS_PROXY 中使用 socks5://

Axios 没有 SOCKS 客户端。proxy: { protocol: 'socks5', … } 和 HTTPS_PROXY=socks5://… 在 1.16.0 及之前以 protocol mismatch(ERR_ASSERTION)失败。从 1.16.1 起,Axios 向 SOCKS 端口发送了一行 HTTP CONNECT,实验的 SOCKS 服务器关闭了连接,请求一直不返回(原因 8)。

修复:在两个 agent 选项中都使用 SOCKS agent,并加上 proxy: false(原因 12)。这样请求在全部十个版本上都经过了实验的 SOCKS5 代理:

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

// socks5h: the proxy resolves the hostname. socks5: this machine does.
const agent = new SocksProxyAgent('socks5h://proxy.example:1080');
const res = await axios.get('https://example.com/', {
  proxy: false,
  httpAgent: agent,
  httpsAgent: agent,
  signal: AbortSignal.timeout(15000),
});
console.log(res.status);

16. 该用 socks5h 却用了 socks5

使用 socks5:// 时,实验的 SOCKS 服务器收到的是 IP 地址:客户端自己解析了主机名。使用 socks5h:// 时,它收到的是主机名(socks-proxy-agent README)。对于只有代理才能解析的名称,socks5:// 以 getaddrinfo ENOTFOUND proxy-only.test 失败,而 socks5h:// 可以正常工作。SOCKS5 与 SOCKS5h 说明了本地 DNS 查询还会泄露什么。

每种需求的可靠配置

三种配置在 Axios 1.19.0、1.20.0、1.21.0 和 1.21.1 上、两条 Node 版本线上都经过了实验代理。在 1.12.2 上只有第三种有效。

在代码中固定一个代理(Axios 1.16.1 或更高版本):

js
import axios from 'axios';

const client = axios.create({
  proxy: {
    protocol: 'http', // how to reach the proxy, not the site
    host: 'proxy.example',
    port: 8080,
    auth: { username: process.env.PROXY_USER, password: process.env.PROXY_PASS },
  },
});

const res = await client.get('https://example.com/', { signal: AbortSignal.timeout(15000) });
console.log(res.status);

来自环境变量的公司代理(Axios 1.16.1 或更高版本)。在代码之外设置变量:

sh
export HTTPS_PROXY=http://proxy.example:8080
export HTTP_PROXY=http://proxy.example:8080
export NO_PROXY=localhost,127.0.0.1
js
import axios from 'axios';

// Started with HTTPS_PROXY, HTTP_PROXY and NO_PROXY in the environment.
// No proxy option, no agent, no httpVersion, default adapter.
const res = await axios.get('https://example.com/', { signal: AbortSignal.timeout(15000) });
console.log(res.status);

每个请求使用不同的代理(所有测试过的版本):

js
import axios from 'axios';
import { HttpsProxyAgent } from 'https-proxy-agent';

const agents = new Map();
const agentFor = (proxyUrl) => {
  if (!agents.has(proxyUrl)) agents.set(proxyUrl, new HttpsProxyAgent(proxyUrl));
  return agents.get(proxyUrl);
};

const viaProxy = (url, proxyUrl) =>
  axios.get(url, { proxy: false, httpsAgent: agentFor(proxyUrl), signal: AbortSignal.timeout(15000) });

const first = await viaProxy('https://example.com/', 'http://proxy-a.example:8080');
const second = await viaProxy('https://example.com/', 'http://proxy-b.example:8080');
console.log(first.status, second.status);

在实验中,两个请求分别从两个不同的代理发出。对于 http:// 地址,再把 http-proxy-agent 的 HttpProxyAgent 作为 httpAgent 传入。

给测试加一道防护

上面的大多数原因都返回 200,所以当一次升级或一个新选项开始绕过代理时,普通的测试套件仍然全部通过。下面这个测试会启动一个替身代理,它记录收到的内容并予以拒绝,然后通过你的应用构建的客户端发送一个请求:

js
import assert from 'node:assert/strict';
import { once } from 'node:events';
import http from 'node:http';
import { test } from 'node:test';
import { createClient } from './client.mjs';

test('the HTTP client sends requests through the proxy', async () => {
  const seen = [];
  // A stand-in proxy: it records what arrives and refuses it, so nothing leaves the machine.
  const proxy = http.createServer((req, res) => {
    seen.push(`${req.method} ${req.url}`);
    res.writeHead(503).end();
  });
  proxy.on('connect', (req, socket) => {
    seen.push(`CONNECT ${req.url}`);
    socket.end('HTTP/1.1 503 Service Unavailable\r\n\r\n');
  });
  proxy.listen(0, '127.0.0.1');
  await once(proxy, 'listening');

  const client = createClient(`http://127.0.0.1:${proxy.address().port}`);
  // .invalid never resolves, so a request that skips the proxy cannot reach a real site.
  await client.get('https://guard.invalid/', { signal: AbortSignal.timeout(5000) }).catch(() => {});
  proxy.close();

  assert.deepEqual(seen, ['CONNECT guard.invalid:443']);
});

createClient(proxyUrl) 是你自己的工厂函数。使用上面“每个请求使用不同的代理”的客户端时,node --test 在五个主要版本上全部通过。给同一个客户端加上 adapter: 'fetch' 之后,它失败了:

code
not ok 1 - the HTTP client sends requests through the proxy
    Expected values to be strictly deep-equal:
    + actual - expected
    + []
    - [
    -   'CONNECT guard.invalid:443'
    - ]
# tests 1
# pass 0
# fail 1
# exit code: 1

该用和该避开的版本

  • 使用 1.21.1,即测试当天的最新版本,或至少使用 1.20.0。升级后检查两件事:proxy: false 与带 proxyEnv 的 agent 同时使用(原因 1),以及重定向到 NO_PROXY 中的主机(原因 14)。
  • 1.16.1 之前:经 HTTP 代理访问 https:// 地址时没有 CONNECT 隧道(原因 5)。请使用 agent 方案或升级。
  • 1.13.0 到 1.19.0 且使用 httpVersion: 2:在 GHSA-3pq3-5fj3-cg6v 的范围内。在 1.20.0 及之后,HTTP/2 仍然忽略 HTTPS_PROXY(原因 2)。
  • 1.15.0 之前和 1.20.0 之前:NO_PROXY 分别无法匹配带结尾点号的主机和 CIDR 网段(原因 13)。
  • Node.js:24.22.2 和 26.13.0 对每个用例的路由结果相同。唯一的区别:通过 fetch 适配器时,Node 26 与实验目标协商了 HTTP/2,而 Node 24 使用 HTTP/1.1。

常见问题

为什么 Axios 忽略 HTTPS_PROXY?

在实验中有六种原因:请求设置了 proxy: false、httpVersion: 2、adapter: 'fetch'、优先级更高的 proxy 对象、命中了 NO_PROXY,或者地址是 http://,这时读取的是 HTTP_PROXY。

使用 Axios 还需要 https-proxy-agent 吗?

在 Axios 1.16.1 或更高版本上使用单个 HTTP 代理时不需要:proxy 对象和 HTTPS_PROXY 会自行建立隧道。旧版本需要它,而且它是为每个请求使用不同代理的最简单方式。

Axios 支持 SOCKS5 代理吗?

不能通过 proxy 或 HTTPS_PROXY 使用。请把 SocksProxyAgent 作为 httpAgent 和 httpsAgent 传入,并加上 proxy: false。

为什么设置了 timeout,Axios 请求经过代理时还是会挂起?

在测试过的版本上,timeout 不覆盖代理不应答 CONNECT 的情况(原因 8)。请加上 signal: AbortSignal.timeout(ms)。

Axios 的 proxy 选项在浏览器中有效吗?

无效。文档把 proxy 标为仅限 Node.js;浏览器使用操作系统或浏览器自身的代理。

相关指南

用真实 IP 测试这个修复。 ipvolt 出售住宅代理,每 GB $2.20 起,以及专用的移动代理,每天 $9 起。把代理填入上面的配置,然后运行快速检查。立即检查代理。

参考来源与延伸阅读

本指南参考的技术资料。请以你所安装版本的文档以及代理服务商支持的配置为准。