# 代理环境变量：HTTP_PROXY 与 NO_PROXY

Source: https://ipvolt.com/zh/guides/proxy-environment-variables
Markdown: https://ipvolt.com/zh/guides/proxy-environment-variables.md
Language: zh-CN

[ipvolt 首页](https://ipvolt.com/zh.md) / [指南](https://ipvolt.com/zh/guides.md) / 代理环境变量：HTTP_PROXY 与 NO_PROXY

故障排查
审校于: 2026-09-11
阅读约 6 分钟
作者： ipvolt

通过一个隔离的本地检查，诊断 HTTP_PROXY、HTTPS_PROXY、ALL_PROXY 和 NO_PROXY 在 curl、Python Requests 和 Node.js 中的路由差异。

## 起点

代理变量可能已经设置，而请求仍然直接发往目标站点。在归咎于网关之前，先检查客户端、目标站点的 scheme 和绕过规则。

## 把目标站点选择与代理连接分开

这些变量是由各个客户端自行解释的约定，而不是操作系统层面能让所有应用都走代理的开关。一条能正常工作的 curl 命令并不能证明另一个库继承或遵守了相同的设置。

变量名通常对应的是目标站点的 scheme。HTTPS_PROXY 中可以填写一个 http:// 代理 URL：目标站点使用 HTTPS，而客户端先连接到一个 HTTP 代理并请求 CONNECT 隧道。代理 URL 的 scheme 描述的是到代理本身的连接。

- http_proxy / HTTP_PROXY：为 HTTP 目标站点选择代理，受客户端的大小写规则约束。
- https_proxy / HTTPS_PROXY：为 HTTPS 目标站点选择代理。
- all_proxy / ALL_PROXY：在 curl 和 Requests 中，当没有适用的目标站点专用代理时作为回退。不要假设每个客户端都实现了它。
- no_proxy / NO_PROXY：当客户端的环境代理选择生效时，为匹配的目标站点请求直连。这是一条路由例外，而不是另一个代理地址。

## 确认实际发出请求的客户端及其版本

本指南的本地路由检查使用了 curl 8.7.1、运行在 Python 3.14.7 上的 Requests 2.34.2，以及 Node.js 26.8.1。Node.js 24.5.0 的发布说明单独记录了其默认 HTTP/HTTPS agent 引入环境代理支持一事；fetch 更早在 24.0.0 就获得了可选启用的支持。这些历史版本只经过文档审阅，并未在此实际执行。

- curl 接受小写的 http_proxy，但有意忽略大写的 HTTP_PROXY，因为 CGI 环境可能从传入的请求头派生出这个名字。HTTPS_PROXY 和 ALL_PROXY 则会被接受。协议专用变量的优先级高于 ALL_PROXY。
- Requests 通常会读取全部四组变量，包括大写名称。其 Python 代理发现逻辑在大小写两者不一致时优先取小写；设置了 REQUEST_METHOD 的 CGI 环境会忽略大写的 HTTP_PROXY。环境值可以覆盖 session.proxies，所以仅靠一个会话字典并不构成隔离边界。
- Node 内置的环境变量支持需要显式启用：以 NODE_USE_ENV_PROXY=1 启动进程。之后默认的 HTTP/HTTPS agent 和原生 fetch 会使用 HTTP_PROXY、HTTPS_PROXY 和 NO_PROXY；小写优先。在这种内置模式下，仅设置 ALL_PROXY 不能作为替代。自定义 agent、dispatcher 和第三方包需要各自单独审查配置。

## 把 NO_PROXY 当作路由变更来对待

先从一个以逗号分隔、只包含确切授权目标主机的列表开始，然后验证哪些请求真正匹配。不要把完整 URL 或路径粘贴进主机列表。在这里讨论的客户端中，通配符 * 会为所有目标站点请求直连；它不适合作为对必需代理的随手修补。

不存在可以在这些客户端之间通用假设的可移植匹配语法。例如，curl 的文档从 7.86.0 起记录了 CIDR 匹配；Node 的内置文档列出了主机名、域名后缀、地址范围和 host:port 条目。在一个客户端中可用的域名条目、通配符或子网，在另一个客户端中需要单独测试。DNS 别名和 IP 字面量也会改变被匹配的名称。

如果某个内部请求意外走了代理，请检查实际的目标主机名和该客户端特有的匹配规则。如果某个外部请求意外直连，请同时检查 NO_PROXY 的大小写两种形式以及任何显式的 agent 配置。只修改该部署获准的路由规则。

## 在没有真实网关的情况下观察代理选择

将下面的内容保存为 proxy_env_lab.py，并在安装了 curl 的环境中运行 python3 proxy_env_lab.py。它会在随机的回环端口上启动两个 HTTP 标记服务器：一个代表直连目标站点，一个代表被选中的代理。代理标记服务器只在本地应答；它不会转发流量，也不会测试 CONNECT、TLS、认证或出口 IP。

每个 curl 进程只接收提供给它的测试环境。--disable 是它的第一个选项，这样个人的 curlrc 就无法改变实验。预期结果依次为 proxy、direct、direct、proxy。这说明即使显式指定了 --proxy，仍然受 NO_PROXY 约束，除非在这个本地诊断中显式清空绕过列表。

### proxy_env_lab.py · Python 3 标准库 + curl

```python
import shutil
import subprocess
import threading
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer

curl = shutil.which("curl")
if not curl:
    raise SystemExit("Install curl before running this local lab")

def marker(label):
    class Handler(BaseHTTPRequestHandler):
        def do_GET(self):
            body = label.encode()
            self.send_response(200)
            self.send_header("Content-Length", str(len(body)))
            self.end_headers()
            self.wfile.write(body)

        def log_message(self, *_):
            pass

    server = ThreadingHTTPServer(("127.0.0.1", 0), Handler)
    threading.Thread(target=server.serve_forever, daemon=True).start()
    return server, "http://127.0.0.1:" + str(server.server_port)

origin, destination = marker("direct")
proxy_server, proxy = marker("proxy")
cases = [
    ("environment", {"http_proxy": proxy}, [], "proxy"),
    ("host bypass", {"http_proxy": proxy, "NO_PROXY": "127.0.0.1"}, [], "direct"),
    ("explicit + bypass", {"NO_PROXY": "127.0.0.1"}, ["--proxy", proxy], "direct"),
    ("explicit + cleared bypass", {"NO_PROXY": "127.0.0.1"},
     ["--proxy", proxy, "--noproxy", ""], "proxy"),
]
try:
    for label, environment, options, expected in cases:
        result = subprocess.run(
            [curl, "--disable", "--silent", "--show-error", "--fail",
             "--connect-timeout", "2", "--max-time", "3", *options, destination],
            env=environment, capture_output=True, text=True, timeout=5,
        )
        if result.returncode or result.stdout != expected:
            raise SystemExit("Local route check failed: " + label)
        print(label + ": " + result.stdout)
finally:
    for server in (origin, proxy_server):
        server.shutdown()
        server.server_close()
```

## 让应用的基线配置成为有意为之

对于必须走代理的 curl 诊断，请同时使用显式的 --proxy 和 --noproxy ''，正如现有的 curl 设置指南所示范的那样。对于 Requests，在请求上提供 proxies 参数；当基线必须忽略继承的代理设置时，使用一个 trust_env=False 的专用 Session。这同时也会停用从环境派生的认证和 CA 证书包配置，因此需要时请显式提供获准的自定义信任证书包。

对于 Node，要么选择经过审查的环境变量启用方式，要么选择显式的兼容 agent/dispatcher。不要假设某个库的自定义 agent 会继承全局设置。确认工作进程或服务实际使用的运行时，而不只是交互式终端里安装的版本。

理解了本地规则之后，用一个授权的目标站点和一个服务商文档中给出的网关做对比。保持 TLS 校验开启，设置截止时间，并通过受控的端点或代理侧观测来确认请求路径。仅凭一个成功的 HTTP 状态码本身无法确定走的是哪条路由。

## 记录决策，但不记录机密

把发出请求的进程的环境与其启动器、容器或服务配置进行比较。记录变量名及其是否已设置、客户端版本、目标站点 scheme 和观测到的路由。避免整个环境的转储、shell 跟踪、详细协议日志和原始异常文本：代理 URL 中可能包含密码。

让获准的密钥管理器私下把所需凭据填充到进程环境中。不要把它们粘贴进命令、提交到环境文件，或把原始配置发给支持团队。环境变量是一种传递机制，而不是保险库。这个本地实验不使用任何凭据，也不涉及 ipvolt 的服务可用性。

## 上线前检查

- 确认实际使用的客户端、运行时版本和目标站点 scheme。
- 检查大写和小写的变量名，但不要记录它们的值。
- 在授权的目标站点上验证 NO_PROXY 匹配和选中的路由。
- 在添加重试之前，先把受控环境与显式配置进行对比。

## 参考来源与延伸阅读

- [Everything curl: proxy environment variables and case rules](https://everything.curl.dev/usingcurl/proxies/env.html)
- [curl manual: --disable, --proxy and --noproxy](https://curl.se/docs/manpage.html)
- [Requests: environment proxy configuration](https://requests.readthedocs.io/en/latest/user/advanced/#proxies)
- [Python: proxy discovery and CGI handling](https://docs.python.org/3/library/urllib.request.html#urllib.request.getproxies)
- [Node.js 24.5.0: environment proxy support in HTTP clients](https://nodejs.org/en/blog/release/v24.5.0)
- [Node.js HTTP documentation: built-in proxy and NO_PROXY rules](https://nodejs.org/docs/latest-v24.x/api/http.html#built-in-proxy-support)

## 相关指南

- [在 curl 中使用代理：-x、环境变量、SOCKS5 与认证](https://ipvolt.com/zh/guides/curl-proxy-setup.md)
- [Python Requests 代理配置：认证与 SOCKS5](https://ipvolt.com/zh/guides/python-requests-proxy.md)
- [在 Node.js fetch 中使用代理](https://ipvolt.com/zh/guides/nodejs-fetch-proxy.md)

## 关于 ipvolt

示例使用通用的代理设置，并附上原始技术文档链接。具体产品的行为请向你的服务商确认。ipvolt 仍在开发中。

[阅读英文原文](https://ipvolt.com/guides/proxy-environment-variables.md)

## 了解何时开放体验。

ipvolt · 开发中

我们正在为开发者和数据团队打造代理基础设施。加入意向名单，ipvolt 就绪时第一时间收到通知。

开放体验时仅发一封通知邮件，不发送其他邮件。

[申请抢先体验](https://ipvolt.com/zh/guides/proxy-environment-variables#waitlist-closing)

[隐私政策](https://ipvolt.com/privacy)

