当前位置: 首页 > news >正文

Http详解

🧱 一、从 TCP 三次握手到访问网页:两层过程

🧩 1. TCP 三次握手(网络传输层)

这是 建立连接 的前提,跟 HTTP 无关,但 HTTP 要依赖它。

举例:你打开浏览器访问 https://example.com,首先浏览器会:

  1. DNS 解析:把 example.com 变成 IP 地址,比如 93.184.216.34
  2. TCP 三次握手
    • 客户端 → 服务器:发送 SYN
    • 服务器 → 客户端:返回 SYN-ACK
    • 客户端 → 服务器:返回 ACK
  3. 至此,TCP 连接建立,后续数据就可以可靠地收发了。

🌐 2. HTTP 请求/响应(应用层)

TCP 建好连接后,才开始发送 HTTP 请求,浏览器会构造一个请求报文:

例如一个 HTTP GET 请求可能是这样的:
GET /index.html HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0)
Accept: text/html,application/xhtml+xml
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

📌 你提到的“扫描请求头的某些东西”,其实就是服务器收到 HTTP 请求后会查看请求头中这些字段,比如:

  • Host:确定你访问的是哪个站点(尤其在一台服务器上部署了多个网站时)
  • User-Agent:知道你用的是浏览器还是爬虫、什么设备
  • Accept / Content-Type:决定返回 HTML、JSON、图片还是别的格式
  • Cookie / Authorization:判断你是否已登录、权限是否足够

🔍 所以你记得的“扫描”是指服务器读取这些请求头来决定如何处理请求,甚至是否允许访问。


🔄 整个访问过程一图理解

你输入网址 → DNS 解析 → TCP 三次握手 → HTTP 请求发送↓                ↓IP地址确定     建立连接(握手)↓浏览器发 HTTP 请求↓服务器读取请求头,决定响应↓HTTP 响应返回内容↓浏览器渲染网页

🔒 那 HTTPS 呢?

如果你访问的是 https://

  • 在 TCP 三次握手之后,还要走一个 TLS 握手(加密协商)
  • 成功后才会开始真正的 HTTP 请求(现在是 加密后的 HTTPS 请求

✅ 总结你记得的“扫描请求头”的部分

你记得的没错,只是:

过程你记得的细节属于哪一层是否“扫描”
TCP 三次握手建立连接(三包)网络层❌ 不看应用内容
HTTP 请求请求头(Host、User-Agent 等)应用层✅ 服务器会检查这些字段
HTTPS加密握手(TLS)网络 + 安全层❌ 请求头被加密,不能被中间人看

下面是一个典型的完整 HTTP 请求头,以浏览器访问 https://www.example.com/index.html 为例,我们使用 GET 方法:


📥 示例:HTTP GET 请求头

GET /index.html HTTP/1.1
Host: www.example.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: session_id=abc123; theme=dark

🧩 各字段解释

字段名含义
GET /index.html HTTP/1.1请求方法 + 路径 + HTTP 版本
Host当前请求目标的域名(多个虚拟主机时必须)
Connection设置 TCP 连接策略,keep-alive 表示复用连接
Cache-Control控制是否使用缓存,这里表示不使用缓存
Upgrade-Insecure-Requests表示浏览器希望从 HTTP 自动升级为 HTTPS
User-Agent表示用户的浏览器、操作系统等信息,服务器可能基于此做响应适配
Accept浏览器希望接受的响应内容类型
Accept-Encoding接受哪种压缩格式的响应内容(比如 gzip)
Accept-Language浏览器接受的语言偏好
Cookie客户端存储的 cookie 数据,用于会话管理、个性化设置等

🔒 如果是 HTTPS 呢?

  • 这些请求头内容是一样的,只不过在 HTTPS 下会经过加密,在网络上传输时是不可见的。
  • 中间人(如 WiFi 路由器)不能读取里面的请求内容(包括头和 body)。

✅ 示例:使用 curl 模拟访问网页(带自定义请求头)

我们来模拟一个访问 https://www.example.com/index.html 的请求,并加上一些常见的请求头:

curl -X GET https://www.example.com/index.html \-H "Host: www.example.com" \-H "Connection: keep-alive" \-H "Cache-Control: max-age=0" \-H "Upgrade-Insecure-Requests: 1" \-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36" \-H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8" \-H "Accept-Encoding: gzip, deflate, br" \-H "Accept-Language: zh-CN,zh;q=0.9" \-H "Cookie: session_id=abc123; theme=dark" \-v

📌 说明:

  • -X GET 明确使用 GET 方法(其实默认就是 GET)。
  • -H 用来设置每一条请求头。
  • -v 表示 verbose 模式,可以显示请求和响应的详细信息(推荐开启!)。

🧪 运行效果(简略版)

运行后你会看到 curl 打印出如下内容:

> GET /index.html HTTP/1.1
> Host: www.example.com
> Connection: keep-alive
> Cache-Control: max-age=0
> Upgrade-Insecure-Requests: 1
> User-Agent: Mozilla/5.0 ...
> Accept: text/html,...
> Accept-Encoding: gzip, deflate, br
> Accept-Language: zh-CN,zh;q=0.9
> Cookie: session_id=abc123; theme=dark
>
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=UTF-8
< Content-Encoding: gzip
< Content-Length: ...
...

你会看到:

  • 上半部分是你发出的请求(带请求头)
  • 下半部分是服务器的响应(状态码、响应头、响应体)

✅ 实战建议

你可以把上面的命令复制到终端执行,只要换一个真实的网址,比如:

curl -X GET https://www.baidu.com \-H "User-Agent: CustomClient/1.0" \-H "Accept: application/json" \-H "Cookie: session_id=xyz999" \-v
PS C:\Users\33895> curl.exe https://httpbin.org/get -H "User-Agent: TestUA" -v
* Host httpbin.org:443 was resolved.
* IPv6: (none)
* IPv4: 198.17.0.206
*   Trying 198.17.0.206:443...
* schannel: disabled automatic use of client certificate
* ALPN: curl offers http/1.1
* ALPN: server accepted http/1.1
* Connected to httpbin.org (198.17.0.206) port 443
* using HTTP/1.x
> GET /get HTTP/1.1
> Host: httpbin.org
> Accept: */*
> User-Agent: TestUA
>
* Request completely sent off
< HTTP/1.1 503 Service Temporarily Unavailable
< Server: awselb/2.0
< Date: Thu, 01 May 2025 14:43:13 GMT
< Content-Type: text/html
< Content-Length: 162
< Connection: keep-alive
<
<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
</body>
</html>
* Connection #0 to host httpbin.org left intact
PS C:\Users\33895>

🔍 命令行回顾

curl.exe https://httpbin.org/get -H "User-Agent: TestUA" -v
  • curl.exe: 使用的是 Windows 系统内置的原始 curl
  • https://httpbin.org/get: 请求的目标 URL(GET 请求)
  • -H "User-Agent: TestUA": 添加自定义请求头
  • -v: verbose 模式,打印详细连接与通信过程

🧾 输出详解

🔹 1. DNS解析 & TCP连接

* Host httpbin.org:443 was resolved.
  • 说明已通过 DNS 查到 httpbin.org 的 IP 地址,并准备连接 443 端口(HTTPS)
* IPv6: (none)
* IPv4: 198.17.0.206
  • 目标主机没有 IPv6 地址,使用 IPv4 198.17.0.206
*   Trying 198.17.0.206:443...
  • 正在尝试与该 IP 的 443 端口建立 TCP 连接

🔹 2. TLS/SSL & ALPN 协议协商

* schannel: disabled automatic use of client certificate
  • schannel 是 Windows 下的 TLS/SSL 库,这里说明未使用客户端证书(默认行为)
* ALPN: curl offers http/1.1
* ALPN: server accepted http/1.1
  • ALPN(Application-Layer Protocol Negotiation)是 TLS 的扩展
  • 表示 curl 提议使用 HTTP/1.1,服务器也接受了

🔹 3. TCP连接成功

* Connected to httpbin.org (198.17.0.206) port 443
* using HTTP/1.x
  • TCP + TLS 握手成功,连接已建立
  • 使用 HTTP/1.x 协议

🔹 4. 请求发送

> GET /get HTTP/1.1
> Host: httpbin.org
> Accept: */*
> User-Agent: TestUA
  • GET /get HTTP/1.1: 请求的方法、路径和协议
  • Host: httpbin.org: 指定目标主机(必需)
  • Accept: */*: 表示接受任意响应类型
  • User-Agent: TestUA: 你自定义的 UA 标识头
* Request completely sent off
  • 表示请求已经完全发送出去

🔹 5. 响应返回

< HTTP/1.1 503 Service Temporarily Unavailable
< Server: awselb/2.0
< Date: Thu, 01 May 2025 14:43:13 GMT
< Content-Type: text/html
< Content-Length: 162
< Connection: keep-alive
  • HTTP/1.1 503: 服务器返回的响应状态码(临时不可用)
  • Server: awselb/2.0: 服务器是 AWS 的 Elastic Load Balancer
  • Date: 响应时间
  • Content-Type: 返回的是 HTML(网页),不是 JSON
  • Content-Length: HTML 内容的长度(162 字节)
  • Connection: keep-alive: 服务器希望保持连接,不马上断开

🔹 6. 响应正文

<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
</body>
</html>
  • 简单的 HTML 页面,提示 503 错误

🔹 7. 连接结束

* Connection #0 to host httpbin.org left intact
  • 表示连接未关闭(keep-alive 生效),curl 不会主动断开,供下次复用

✅ 总结

这个 verbose 输出涵盖了:

阶段内容
DNS解析查到 IP 地址
TCP连接与服务器建立连接
TLS握手通过 ALPN 确定使用 HTTP/1.1
请求内容打印发出的 HTTP 请求头
响应头打印服务器返回的响应状态和内容类型
响应体HTML 错误页
连接处理保持连接未关闭
PS C:\Users\33895> curl.exe "https://www.baidu.com/s?wd=test"
<a href="https://wappass.baidu.com/static/captcha/tuxing_v2.html?&amp;logid=7987820460167506860&amp;ak=c27bbc89afca0463650ac9bde68ebe06&amp;backurl=https%3A%2F%2Fwww.baidu.com%2Fs%3Fwd%3Dtest&amp;ext=x9G9QDmMXq%2FNo87gjGO0P7zYlbLsT8y8wKbl0sIMQh9WkhrGqVqihBVl6ZY8QtPHUgqUK9LXd1cIlztrhMwiv5LGqKWhTZD8Q7xZpGkscD5m9BVI2WSf6oW03O5A8dkk&amp;signature=b7d7e5b0fc3623b54c550ff291d55c76&amp;timestamp=1746111289">Found</a>.

你这个请求遇到了百度的 反爬虫/验证码重定向机制。我们来逐步解析发生了什么:


📌 现象说明:

你访问的是:

bash复制编辑
curl.exe "https://www.baidu.com/s?wd=test"

返回的内容却是这样的一段:

html复制编辑
<a href="https://wappass.baidu.com/static/captcha/tuxing_v2.html?...">Found</a>.

这说明:

✅ 百度确实返回了 302 重定向(跳转到验证码页面):

  • 当百度认为你的请求不是“真实用户”发起的(比如没有浏览器行为、没有 cookies、没有 JS 执行环境),它会:
    • 返回一个 302 重定向
    • 重定向目标是一个图形验证码页面,提示你要“点点验证码”验证你是人类

🔍 为什么你会被拦?

百度会检测以下条件:

检测点描述
User-Agent是否是常见浏览器
Referer是否从网页点击过来的
Cookie有没有已有的身份信息(如百度登录或搜索行为)
JS行为是否会执行 JavaScript,返回行为数据(curl 不会)

✅ 如何“伪装浏览器”避免被立即拦?

你可以模拟常见浏览器的请求头,比如:

bash复制编辑curl.exe "https://www.baidu.com/s?wd=test" ^-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/122.0.0.0 Safari/537.36" ^-H "Accept: text/html" ^-H "Referer: https://www.baidu.com" ^-H "Accept-Language: zh-CN,zh;q=0.9" ^-L ^-v

参数说明:

  • -H: 模拟请求头
  • -L: 自动跟随重定向(避免只看到 302)
  • -v: 查看详细过程

⚠️ 即便如此,百度仍然可能返回验证码页面,因为它用 JS + 图形验证码判断你是不是“机器人”。


✅ 正确调试方式建议:

如果你只是想学习和调试 HTTP 请求:

  • 使用 httpbin.orghttpbingo.orgreqres.in 这类测试服务器
  • 或自己搭个简单 Flask/FastAPI 服务,方便测试请求和响应内容

🚫 不建议用 curl 大规模抓百度网页:

百度、谷歌、B站、微博等大厂都启用了 复杂的反爬虫机制,用 curl 是“裸奔”方式,很容易被 ban,甚至封 IP。

相关文章:

  • AI日报 · 2025年05月01日|DeepSeek 发布新一代定理证明模型 Prover V2
  • 【数据结构】 复杂度
  • 2025五一杯数学建模竞赛选题建议+初步分析
  • OpenGL-ES 学习(9) ---- OpenGL-ES 简介和基本 Pipeline
  • 专题二十一:无线局域网——WLAN
  • Python地图绘制模块cartopy入门
  • Java学习手册:Spring 数据访问
  • PostgreSQL数据类型
  • 面试中系统化地解答系统设计题:通用方法论
  • 向量数据库和关系型数据库的区别,优点,缺点和典型应用场景
  • Linux安全清理删除目录bash脚本
  • 从零到一构建数据科学全流程实战:最新技术与企业级开发
  • Python:Python3 异常和文件
  • Rerank详解
  • 【CF】Day48——Codeforces Round 979 (Div. 2) D
  • 数字智慧方案5981丨智慧农业解决方案(55页PPT)(文末有下载方式)
  • 2024年12月 C/C++(二级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • 开始一个vue项目
  • Android 移动开发:ProgressBar (水平进度条)
  • 第十一届蓝桥杯 2020 C/C++组 门牌制作
  • 长三角铁路持续迎五一出行高峰:今日预计发送旅客418万人次
  • 韩国代总统、国务总理韩德洙宣布辞职
  • 证监会:坚决拥护党中央对王建军进行纪律审查和监察调查决定
  • 解放日报:上海深化改革开放,系统集成创新局
  • 国有六大行一季度合计净赚超3444亿,不良贷款余额均上升
  • 国家统计局:一季度全国规模以上文化及相关产业企业营业收入增长6.2%