HTTP代理到底做了什么
很多人对代理的印象只停留在"换一个IP"上,其实从协议层面看,HTTP 代理干的事情非常具体:它坐在客户端和目标网站中间,把客户端发出来的 HTTP 请求接过来,按自己的规则检查、改写或直接原样转发,再把目标网站返回的响应回传给客户端。
这个"中间人"位置决定了它的三个天然能力:第一,目标网站看到的是代理的地址,不是你本机的地址;第二,你可以在代理这一侧集中做认证、限速、记录日志;第三,你可以按照业务需要,把不同请求分派到不同的出口上去。
理解代理,只要抓住三件事就够了:请求是怎么被转发的、头部字段是怎么被改写和补充的、加密流量在什么时候切换成隧道模式。下面逐一说清楚。
请求转发:一条请求怎么被"接力"出去
普通的直连请求,请求行里写的是路径,比如 GET /index.html HTTP/1.1,因为目标主机已经在 Host 头部里说清楚了。但发给代理的请求不一样——代理本身就是一台服务器,它需要知道"你要我替你去访问谁",所以请求行必须带上完整地址,也就是所谓的绝对 URI 形式。
GET http://www.example.com/index.html HTTP/1.1
Host: www.example.com
Proxy-Authorization: Basic dXNlcjpwYXNz
User-Agent: Mozilla/5.0
Connection: keep-alive
代理收到这条请求后,大致按下面几步处理:
1)先看 Proxy-Authorization,校验账号密码或者来源 IP 是否在允许名单内,不通过就直接返回 407。
2)解析请求行里的完整地址,取出目标主机和端口,自己作为客户端去和目标网站建立连接。
3)把请求行从绝对 URI 改写回路径形式,补上或修正必要头部,再发给目标网站。
4)目标网站响应后,代理把响应原样回传给客户端。
如果你用的是命令行工具,一行参数就能验证这个过程——加 -v 可以看到请求行确实变成了完整地址。
curl -x http://用户名:密码@代理地址:端口 -v http://www.example.com/index.html
这里有个容易被忽略的细节:代理转发并不是"复制粘贴"。请求行的形式变了、部分和代理相关的头部被消费掉了、有时还会追加新的头部。这也是为什么抓包对比直连和走代理的请求,会发现两边内容并不完全一样。
头部字段:代理链路里的"留言条"
HTTP 协议靠头部字段沟通,代理链路上一共有三方:客户端、代理、目标网站。不同字段属于不同的"对话对象",搞混了就会出现把代理密码发给目标网站这种低级问题。
| 字段 | 方向 | 作用 | 是否转发给目标站点 |
|---|---|---|---|
| Proxy-Authorization | 客户端 → 代理 | 向代理证明身份,通常是 Basic 认证 | 不转发 |
| Proxy-Connection | 客户端 → 代理 | 历史遗留字段,用来协商与代理之间的连接保持 | 不转发 |
| Via | 代理 → 目标站点 | 标记这条请求经过了哪个代理、用的什么协议版本 | 由代理追加 |
| X-Forwarded-For | 代理 → 目标站点 | 把客户端来源地址追加进列表,链路上可能有多层 | 由代理追加 |
| Host | 客户端 → 目标站点 | 指明真正要访问的站点,走代理时同样必须有 | 转发 |
几个实操中经常踩到的点:
Proxy-Authorization 只对代理有效。它的作用域止于代理,代理校验完就"吃掉"这个字段,不会再传给目标网站。反过来,目标网站的 Authorization 也和代理认证毫无关系,两者不要混用。
X-Forwarded-For 只能当参考。它是纯文本追加的,客户端完全可以自己伪造一个值。如果你打算拿它做访问控制或者风控依据,基本等于没设防。真正可信的做法是在代理这一侧记录连接的真实来源,而不是读请求头。
Via 是链路的"打卡记录"。多层代理叠加时,Via 里会依次出现多个节点。有些场景下你并不希望目标网站看到这条链路信息,那就需要在代理配置里关掉它的添加行为,具体取决于服务方是否提供该选项。
连接复用别忽略。现代实现里,控制连接是否保持的是标准字段 Connection: keep-alive,Proxy-Connection 只是为了兼容很老的客户端而存在。如果你的程序走代理时连接总是频繁重建,先检查这两个头部的协商情况。
隧道模式:CONNECT 与加密流量的透传
前面讲的转发方式有个前提——代理能看懂请求内容。但访问 HTTPS 站点时,请求内容是加密的,代理既看不到路径也改不了头部,这时候就要换成隧道模式。
做法是客户端先向代理发一个 CONNECT 请求,明确告诉代理"帮我把到某个主机某个端口的 TCP 连接打通":
CONNECT www.example.com:443 HTTP/1.1
Host: www.example.com:443
Proxy-Authorization: Basic dXNlcjpwYXNz
代理如果允许,就回一个状态行,之后这条连接就变成一根"管道":
HTTP/1.1 200 Connection Established
从这一刻起,代理不再解析任何 HTTP 内容,只是在客户端和目标站点之间原样搬运字节。TLS 握手、证书校验、加密的应用数据,全都在客户端和目标网站之间端到端完成,代理只负责流量通行。
这样设计带来两个直接结果,值得记住:
第一,隧道里代理没法再改写头部,所以走 HTTPS 时你通常看不到 X-Forwarded-For 之类的痕迹,链路更"干净"。
第二,隧道一旦建立,出口就固定在这条 TCP 连接上。想让下一个请求走不同的出口,需要结束当前隧道、重新发起连接。
另外,长连接和并发量大的业务要注意隧道的建立开销:每建一次隧道都是一次额外的往返,池化复用做得好不好,直接体现在整体的响应速度上。
正向代理与反向代理,别搞反了
上面讲的都是正向代理——服务于客户端,替客户端去访问外部站点。反向代理则相反,它站在服务器一侧,替服务器接收外部请求。两者在协议层面用的是同一套东西,但服务对象完全不同。
| 对比项 | 正向代理 | 反向代理 |
|---|---|---|
| 服务对象 | 客户端 / 发起请求的一方 | 服务端 / 提供内容的一方 |
| 谁配置它 | 使用者自己在程序或系统里设置 | 网站运营方在服务端部署 |
| 目标网站看到的是 | 代理的地址 | 反向代理的地址 |
| 典型用途 | 更换出口、分散请求来源、集中管理访问 | 负载均衡、缓存加速、统一入口 |
| 认证字段 | 使用 Proxy-Authorization | 通常不使用该字段 |
做数据采集、多账号管理、网络测试这类工作,用的基本都是正向代理,也就是常说的代理 IP 服务。
把这些特性用起来:选代理服务的几个检查项
理解了协议细节,再回头看选服务就清晰多了。对照前面的知识点,可以重点看这几项:
协议覆盖是否齐全。至少要支持 HTTP、HTTPS 与 SOCKS5。只支持 HTTP 的服务在遇到隧道模式或者非 HTTP 协议时会很别扭。
认证方式是否双通道。账密认证(走 Proxy-Authorization)和终端 IP 白名单认证各有适用场景:程序化调用用账密更方便,固定服务器出口用白名单更省事。
隧道模式是否稳定。HTTPS 站点是主流,CONNECT 建连的成功率和隧道复用能力,直接决定实际可用性。
提取与管理方式。是否提供 API 接口按需提取、是否支持批量管理,这决定了能不能接进你现有的调度逻辑。
出口是否可控。能否按地区、按数量、按使用时长选择,独享与共享是否可区分,这些都会影响业务表现。
天启HTTP 作为国内的代理 IP 服务商,在这些点上的对应能力是:支持 HTTP、HTTPS、SOCKS5 协议,提供短效与长效等不同类型的代理资源,支持用户名密码认证与终端 IP 白名单两种接入方式,并提供 API 接口提取,方便接入自己的请求调度程序。针对需要走 CONNECT 隧道的 HTTPS 场景,也可以用统一入口的方式简化配置。
接入的代码成本其实很低。以 Python 的 requests 为例,改一行代理参数就能完成从直连到走代理的切换:
import requests
proxies = {
"http": "http://用户名:密码@代理地址:端口",
"https": "http://用户名:密码@代理地址:端口",
}
resp = requests.get("http://www.example.com/index.html", proxies=proxies, timeout=10)
print(resp.status_code)
注意 https 那一项填的仍然是 http:// 开头的代理地址——因为这里指的是"用 HTTP 代理去访问 HTTPS 站点",底层走的就是上面讲的 CONNECT 隧道,这是很多人第一次配置时最容易写错的地方。
常见问题
Q:HTTP 代理能访问 HTTPS 网站吗?
可以。客户端会先用 CONNECT 方法让代理建立一条到目标 443 端口的隧道,之后加密数据在隧道里原样透传,代理看不到具体内容,但连接是通的。
Q:为什么走代理后,目标网站看不到我的真实 IP?
因为请求是由代理服务器发起的,目标网站的对端地址就是代理的地址。除非代理主动在 X-Forwarded-For 里追加来源信息,否则目标侧拿不到你的本机地址。
Q:X-Forwarded-For 里的 IP 可信吗?
不可信。这个字段是客户端也能自己写的纯文本,代理只是往里追加。做访问控制时应该以代理侧记录的真实连接来源为准,而不是读这个头部。
Q:Proxy-Authorization 会不会泄露给目标网站?
不会。它只在客户端和代理之间有效,代理校验完成后不会转发。如果担心凭证泄露,优先使用终端 IP 白名单认证,连凭证都不用出现在请求里。
Q:隧道模式下为什么换 IP 不生效?
隧道是一条已经建立的 TCP 连接,出口在建立时就已经确定。想让新请求走新的出口,需要关闭当前连接、重新发起 CONNECT。
Q:请求转发和隧道模式,业务中该怎么选?
访问 HTTP 站点时用普通转发即可,配置简单、链路信息完整;访问 HTTPS 站点会自动走隧道模式,此时更看重代理的建连成功率和连接复用能力。





