HTTP 协议全解:从报文结构到 HTTPS 加密原理
HTTP 是 Web 世界的"通用语言",理解它的报文格式、请求方法、Cookie/Session 机制以及 HTTPS 加密原理,是每一位 Java 后端开发者必须打好的地基。本文从抓包工具实战入手,带你逐行拆解请求/响应报文,并延伸到状态码、版本演进与网络安全,一站式建立完整的 HTTP 知识体系。
目录
- 一、HTTP 协议概述
- 二、抓包工具与 Fiddler 实战
- 三、GET 请求报文
- 四、POST 请求报文
- 五、HTTP 响应报文
- 六、核心概念:URL / 请求方法 / 请求头 / Referer
- 七、Cookie 与 Session
- 八、HTTP 响应状态码
- 九、Java 代码实战(HttpClient)
- 十、HTTPS 加密原理
- 十一、HTTP 各版本差异对比
一、HTTP 协议概述
HTTP(HyperText Transfer Protocol,超文本传输协议)是位于应用层的协议。HTTP/1.1、HTTP/2 的传输层都是 TCP;而 HTTP/3(注意不是 3.0)引入了 QUIC 协议------QUIC 基于 UDP 实现,但自己在应用层重新实现了可靠传输与拥塞控制,弥补了 UDP 不可靠的缺点。

此外,在分布式系统中,服务之间的相互调用也越来越常见。Java 微服务兴起后,Spring Cloud 这类框架内部正是通过 HTTP 进行通信,以便与 Spring MVC 无缝衔接。
HTTP 是一种"一问一答"(请求---响应)的协议。根据通信双方的交互模式,可以分为以下几种:
- 1 问 1 答:最常见,一个请求对应一个响应。
- 1 多:服务器向客户端推送多个响应,例如下载大文件时的流式响应。
- 多 多:双方持续互发,例如远程桌面。
- 多 1:客户端分多次发送,服务器最终返回一个响应,例如上传大文件。
二、抓包工具与 Fiddler 实战
抓包工具本质上相当于一个代理。正常情况下,浏览器与服务器是直接连接的;但当我们插入一个抓包工具后,浏览器会先连到这个工具,再由它转发给服务器,从而能够截取并查看通信内容。

上图是最常见的抓包工具,功能强大但学习成本较高。本文我们仅演示 Fiddler,它使用起来更简单。

下载完成后效果如下:
点击 Tools -> Options,将相关选项全部勾选:
然后我们在浏览器中输入以下地址:
text
https://www.sogou.com/

即可抓取到如下请求:

上方是请求(Request),下方是响应(Response)。前端代码是我们能拿到的(相当于公开的),而服务端逻辑我们是拿不到的。建议统一查看 raw(原始报文) 视图:
上方为请求的原始报文:
下方为响应的原始报文:
提示:这个软件建议用的时候再开,不要没事一直挂着。报文整体格式如下:

三、GET 请求报文
一个典型的 GET 请求报文如下:
http
GET https://main.vscode-cdn.net/extensions/marketplace.json HTTP/1.1
Host: main.vscode-cdn.net
Connection: keep-alive
Sec-Fetch-Site: none
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: empty
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Accept-Encoding: gzip, deflate, br, zstd
请求行
第一行即为请求行,遇到第一个换行符即结束,格式为:方法 URL 版本。上例中方法为 GET,URL 为 https://main.vscode-cdn.net/extensions/marketplace.json,版本为 HTTP/1.1。
请求报头(Header)
从 Host 开始直到请求正文之前的所有内容,都是请求报头。
空行
报头与正文之间有一个空行作为分隔。它在截图中无法直观体现,但确实存在。
请求正文(Body)
GET 请求通常没有请求正文。
四、POST 请求报文
与 GET 不同,POST 请求带有请求正文。下面是一段经过脱敏处理的真实 POST 报文(登录请求):
http
POST https://passport2.chaoxing.com/fanyalogin HTTP/1.1
Host: passport2.chaoxing.com
Connection: keep-alive
Content-Length: 225
sec-ch-ua-platform: "Windows"
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0
Accept: application/json, text/javascript, */*; q=0.01
sec-ch-ua: "Not;A=Brand";v="8", "Chromium";v="150", "Microsoft Edge";v="150"
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
sec-ch-ua-mobile: ?0
Origin: https://passport2.chaoxing.com
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://passport2.chaoxing.com/login?fid=&newversion=true&refer=https%3A%2F%2Fwww.chaoxing.com%2F
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cookie: fid=6789; xxtenc=2d74a9c31e5870b26d9f41c8e30567b1; JSESSIONID=7A92F158C402DE7193652AF47B193CD6; route=8b29d71f5e034792c651fa0d794e1c35; retainlogin=5
fid=-1&uname=5s2Gz3%2Fm%2BXpQ91nDv7RbA%3D%3D&password=z7DqF4N2bT9cH3%2FAx5LmP%3D%3D&refer=https%253A%252F%252Fwww.chaoxing.com%252F&t=true&forbidotherlogin=0&validate=&doubleFactorLogin=0&independentId=0&independentNameId=0
(注:以上报文已做脱敏处理。)
请求头
http
Host: passport2.chaoxing.com
Connection: keep-alive
Content-Length: 225
sec-ch-ua-platform: "Windows"
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0
Accept: application/json, text/javascript, */*; q=0.01
sec-ch-ua: "Not;A=Brand";v="8", "Chromium";v="150", "Microsoft Edge";v="150"
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
sec-ch-ua-mobile: ?0
Origin: https://passport2.chaoxing.com
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://passport2.chaoxing.com/login?fid=&newversion=true&refer=https%3A%2F%2Fwww.chaoxing.com%2F
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cookie: fid=6789; xxtenc=2d74a9c31e5870b26d9f41c8e30567b1; JSESSIONID=7A92F158C402DE7193652AF47B193CD6; route=8b29d71f5e034792c651fa0d794e1c35; retainlogin=5
请求正文
空行下面的那一行即为请求正文:
text
fid=-1&uname=5s2Gz3%2Fm%2BXpQ91nDv7RbA%3D%3D&password=z7DqF4N2bT9cH3%2FAx5LmP%3D%3D&refer=https%253A%252F%252Fwww.chaoxing.com%252F&t=true&forbidotherlogin=0&validate=&doubleFactorLogin=0&independentId=0&independentNameId=0
五、HTTP 响应报文
http
HTTP/1.1 200 OK
Date: Fri, 10 Jul 2026 06:26:26 GMT
Content-Type: text/html;charset=utf-8
Content-Length: 57
Connection: keep-alive
Set-Cookie: fid=2333; Domain=.chaoxing.com; Expires=Sun, 09-Aug-2026 06:26:26 GMT; Path=/
Set-Cookie: _uid=347267151; Domain=.chaoxing.com; Path=/
Set-Cookie: _d=1783664786992; Domain=.chaoxing.com; Path=/
Set-Cookie: UID=347267151; Domain=.chaoxing.com; Path=/
Set-Cookie: vc3=ZEULMrYbOUWxWtSNyhjsNG5zBmI8jhlymxQSx%2BNeePqY3I%2B%2BfSJ9Y0qkWV60BG6%2Fv9K%2FZuEJ13RfgBKJI9%2BR44YUUxCm%2B1Kmw32Cl%2FvY15y%2B6Av2o6OIqTFshbpI6YTTgzKWvvS9SayX1kfcBJp4uVLG2Z%2BRYSoBAEHRXGAsL5A%3D11e37b7b197a16c3c6cf219923af40b9; Domain=.chaoxing.com; Path=/; HttpOnly
Set-Cookie: uf=da0883eb5260151eabb1984833a1439d708a0fbd21fdc779583525884a9ca81d509b1fe8ce235650441f0c5d5f44805f81a6c9ddee30899fd807a544f7930b6aed1e6c11a143bb563b0339d97cdac4ba94046878e2708015e5851b744f8aa02c9fb3947ed09a594c129f6968bc6e8781523cf062b4ec1cb656a6092da4e3071ff3c3ccd3926764e2e6f2df66f5a95a7e70b5a05e402d2a6370184964ffe8c27cb95a7bfad6ce77e16eb5b8dc84f2a84eb1f899d50c1c3fa3aa2ebad65cd196bb; Domain=.chaoxing.com; Path=/
Set-Cookie: cx_p_token=891ea1d12343b13d93310c74ec5c1961; Domain=.chaoxing.com; Path=/
Set-Cookie: p_auth_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIzNDcyNjcxNTEiLCJsb2dpblRpbWUiOjE3ODM2NjQ3ODY5OTQsImV4cCI6MTc4NDI2OTU4Nn0.VV8-r9njCTQwikdY6pBiuh6bzYsnWAIOVN6ZEA6LXB4; Domain=.chaoxing.com; Path=/; HttpOnly
Set-Cookie: xxtenc=8f51b4f76d824ee45498373d913ff6c9; Domain=.chaoxing.com; Expires=Sun, 09-Aug-2026 06:26:26 GMT; Path=/
Set-Cookie: DSSTASH_LOG=C_38-UN_967-US_347267151-T_1783664786994; Domain=.chaoxing.com; Path=/
Origin-Agent-Cluster: ?0
Strict-Transport-Security: max-age=31536000; includeSubDomains
{"url":"https%3A%2F%2Fwww.chaoxing.com%2F","status":true}
状态行
http
HTTP/1.1 200 OK
响应报头
http
Date: Fri, 10 Jul 2026 06:26:26 GMT
Content-Type: text/html;charset=utf-8
Content-Length: 57
Connection: keep-alive
Set-Cookie: fid=2333; Domain=.chaoxing.com; Expires=Sun, 09-Aug-2026 06:26:26 GMT; Path=/
Set-Cookie: _uid=347267151; Domain=.chaoxing.com; Path=/
Set-Cookie: _d=1783664786992; Domain=.chaoxing.com; Path=/
Set-Cookie: UID=347267151; Domain=.chaoxing.com; Path=/
Set-Cookie: vc3=ZEULMrYbOUWxWtSNyhjsNG5zBmI8jhlymxQSx%2BNeePqY3I%2B%2BfSJ9Y0qkWV60BG6%2Fv9K%2FZuEJ13RfgBKJI9%2BR44YUUxCm%2B1Kmw32Cl%2FvY15y%2B6Av2o6OIqTFshbpI6YTTgzKWvvS9SayX1kfcBJp4uVLG2Z%2BRYSoBAEHRXGAsL5A%3D11e37b7b197a16c3c6cf219923af40b9; Domain=.chaoxing.com; Path=/; HttpOnly
Set-Cookie: uf=da0883eb5260151eabb1984833a1439d708a0fbd21fdc779583525884a9ca81d509b1fe8ce235650441f0c5d5f44805f81a6c9ddee30899fd807a544f7930b6aed1e6c11a143bb563b0339d97cdac4ba94046878e2708015e5851b744f8aa02c9fb3947ed09a594c129f6968bc6e8781523cf062b4ec1cb656a6092da4e3071ff3c3ccd3926764e2e6f2df66f5a95a7e70b5a05e402d2a6370184964ffe8c27cb95a7bfad6ce77e16eb5b8dc84f2a84eb1f899d50c1c3fa3aa2ebad65cd196bb; Domain=.chaoxing.com; Path=/
Set-Cookie: cx_p_token=891ea1d12343b13d93310c74ec5c1961; Domain=.chaoxing.com; Path=/
Set-Cookie: p_auth_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIzNDcyNjcxNTEiLCJsb2dpblRpbWUiOjE3ODM2NjQ3ODY5OTQsImV4cCI6MTc4NDI2OTU4Nn0.VV8-r9njCTQwikdY6pBiuh6bzYsnWAIOVN6ZEA6LXB4; Domain=.chaoxing.com; Path=/; HttpOnly
Set-Cookie: xxtenc=8f51b4f76d824ee45498373d913ff6c9; Domain=.chaoxing.com; Expires=Sun, 09-Aug-2026 06:26:26 GMT; Path=/
Set-Cookie: DSSTASH_LOG=C_38-UN_967-US_347267151-T_1783664786994; Domain=.chaoxing.com; Path=/
Origin-Agent-Cluster: ?0
Strict-Transport-Security: max-age=31536000; includeSubDomains
空行
报头与正文之间同样存在一个空行作为分隔。
响应正文
text
{"url":"https%3A%2F%2Fwww.chaoxing.com%2F","status":true}
六、核心概念:URL / 请求方法 / 请求头 / Referer
URL 结构
以如下 URL 为例:

https://passport2.chaoxing.com/login?fid=&newversion=true&refer=https%3A%2F%2Fwww.chaoxing.com%2F
早期 URL 中可以直接携带 user:pass@ 形式的登录信息,现在已基本弃用,改为在页面表单中填写。
端口号虽然没有显式写出,但浏览器会补全一个默认值(注意这是浏览器给的,不是操作系统默认):
- HTTP 不写端口时默认为
80; - HTTPS 不写端口时默认为
443; - Spring Boot 默认端口为
8080。
| 组成部分 | 是否存在 | 核心原因 |
|---|---|---|
| 协议 | 是 | 替换为加密 HTTPS |
| user:pass@认证 | 否 | 登录信息放 POST 请求体,URL 明文携带账号密码不安全 |
| 域名地址 | 是 | 必须指定目标网站 |
| 端口号 | 不显式写出 | HTTPS 默认 443,默认端口可省略 |
| 资源路径 | 是 | 标记登录页面地址 |
| ? 查询参数 | 是 | 携带页面跳转、版本配置参数 |
| #锚点片段 | 否 | 无需页面内跳转定位,无使用场景 |
关于"资源路径",可以想象 B 站服务器上有一个 video 目录,目录里有一个名为 BV1jtHYzfE2r 的视频文件(也可能是对该 BV 号解析后的结果)。
**URL 编码(URL Encode)**就是把特殊字符进行编码。例如 https%3A%2F%2Fwww.chaoxing.com%2F 原本应该是 https://www.chaoxing.com/。URL 里只能直接使用英文字母、数字以及少数符号(- _ . ~);中文、空格以及 / ? & = : @ # 这类特殊字符会与网址语法冲突,导致服务器解析错乱。
URL 编码 = 把这些不能直接放入网址的字符,转换为 % + 两位十六进制数字,从而保证 URL 合法、不产生歧义。
拆解对应关系:
:→%3A/→%2F
请求方法(Method)

常见的 HTTP 方法:
GET:获取资源;POST:提交/发送资源;PUT:上传/投递资源;DELETE:删除资源。
但在实际开发中,这些方法的使用已经比较"灵活"------GET 也能发送数据,POST 也能获取资源,并不完全拘泥于语义。
典型的 GET 请求如下:
http
GET https://main.vscode-cdn.net/extensions/marketplace.json HTTP/1.1
Host: main.vscode-cdn.net
Connection: keep-alive
Sec-Fetch-Site: none
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: empty
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Accept-Encoding: gzip, deflate, br, zstd
GET 一般没有 Body,数据通过 URL 路径或查询参数传递。例如 https://main.vscode-cdn.net/extensions/marketplace.json 中的 /extensions/marketplace.json 就是路径。
POST 一般用于登录和上传文件,示例如下:
text
fid=-1&uname=5s2Gz3%2Fm%2BXpQ91nDv7RbA%3D%3D&password=z7DqF4N2bT9cH3%2FAx5LmP%3D%3D&refer=https%253A%252F%252Fwww.chaoxing.com%252F&t=true&forbidotherlogin=0&validate=&doubleFactorLogin=0&independentId=0&independentNameId=0
这正是请求正文(Body)中的内容,包含用户名与密码(均为加密后的密文)。
GET 与 POST 的区别:
严格来说,GET 和 POST 没有本质区别,二者可以互相替代。常见的区别主要体现在约定俗成的用法上:
- 语义不同:GET 通常表示获取数据,POST 通常表示提交数据。
- 数据位置不同:GET 一般通过 Query String 传参,POST 一般把数据放在 Body 中。
- 幂等性:GET 通常被实现为"一请求对应一结果"(即幂等),POST 则没有幂等性要求------但这只是建议,并非强制。如果请求是幂等的,就可以做缓存。
误区:认为"GET 不安全、POST 安全"是错误的结论。两者都明文传输,安全性并无本质差异,真正的安全要靠 HTTPS。

Content-Type 与 Content-Length 这两个请求头都是伴随 Body 出现的(前文已出现):
text
Content-Type: text/html;charset=utf-8
Content-Length: 57
Content-Type 常见取值:
text/htmltext/cssapplication/javascriptapplication/jsonimage/jpegimage/pngtext/plain
在前端开发中,常把 HTML 比作骨、CSS 比作皮、JS 比作魂。HTML/CSS/JS 这类静态资源变更频率低,因此通常会被浏览器缓存;强制刷新(Ctrl + F5)就是清除缓存,所以刷新后我们能抓到更多请求,因为相当于重新访问了。
另外要注意:CSS、JS 在开发阶段是有换行的,但上线时会用专门的工具进行压缩,删除空格、替换变量名。此外还有 form 表单格式,也是 Body 的一种常见编码方式。
HTTP 的粘包/拆包问题
HTTP 同样存在"粘包/拆包"问题:HTTP/1.1、HTTP/2 都基于 TCP,而 TCP 是字节流,需要依靠 Content-Length 或分块传输(chunked)来界定消息边界。
Referer
Referer 表示"本次请求是从哪个页面跳转过来的"。它与浏览器的前进/后退功能无关,而是发送给服务端的一个请求头。
举例来说,假设广告商场景:我在 B 网页点击了 A 的广告并进入了 A 的链接,对广告商而言,它会记录 Referer 为 B,从而向 B 结算推广费用。
那么 Referer 有没有可能被伪造/替换呢?------这正是我们引入加密的原因。
HTTPS 会对 HTTP 的报头、空行、正文全部 进行加密(TLS 加密的是整个 HTTP 报文)。运营商(ISP)没有服务器私钥,无法解密内容,更无法篡改;只有持有私钥的通信双方才能解密。早期依赖 SNI 还能看到目标域名,而现在 ECH(Encrypted Client Hello,加密客户端 Hello) 进一步隐藏了域名。
七、Cookie 与 Session
1. 登录验证阶段
- 浏览器向服务器发送登录请求(包含用户名和密码)。
- 服务器验证数据库中的账号密码是否正确。
2. Session 创建与 Cookie 下发
- 验证通过后,服务器会为该客户端创建一个唯一的会话对象(Session)。
- 服务器内部维护着一个
HashMap,以sessionId为 key ,以session对象为 value 进行存储(Session 里存什么由程序员自行定义)。 - 服务器将生成的
sessionId通过 Cookie 返回给浏览器。
3. 后续请求维持
- 浏览器后续访问其他页面(如主页)时,会自动携带此前服务器返回的 Cookie(包含
sessionId)。 - 服务器接收到请求后,通过 Cookie 里的
sessionId去自己的HashMap中查找对应的会话对象,从而识别出用户身份并提供对应服务。
八、HTTP 响应状态码
状态码位于响应报文的首行。常见分类如下:
- 2xx 成功 :
200 OK表示一切正常。 - 4xx 客户端错误 :
403 Forbidden:服务器拒绝请求,通常是权限不足、访问了不该访问的资源。404 Not Found:请求的资源不存在。405 Method Not Allowed:服务器不支持该请求方法。
- 5xx 服务端错误 :
500 Internal Server Error:服务器内部出错("挂了")。504 Gateway Timeout:网关(服务器端)超时,服务器繁忙。
- 3xx 重定向 :
302 Found:临时重定向。301 Moved Permanently:永久重定向(浏览器可做缓存)。
为方便记忆,下表汇总了状态码的完整分类:
| 类别 | 含义 | 常见状态码 |
|---|---|---|
| 1xx 信息性 | 请求已收到,继续处理 | 100 Continue |
| 2xx 成功 | 请求正常处理完毕 | 200 OK、201 Created、204 No Content |
| 3xx 重定向 | 需要后续操作才能完成请求 | 301 永久移动、302 临时移动、304 Not Modified(命中缓存,不返回正文) |
| 4xx 客户端错误 | 请求有语法错误或无法完成 | 400 Bad Request、401 Unauthorized、403 Forbidden、404 Not Found、405 Method Not Allowed |
| 5xx 服务端错误 | 服务器处理请求出错 | 500 Internal Server Error、502 Bad Gateway、503 Service Unavailable、504 Gateway Timeout |
口诀:2 成功、3 跳转、4 你错、5 我错。304 虽然归类在 3xx,但实际是"用了缓存,没重新传正文",面试常考。
九、Java 代码实战(HttpClient)
下面用 Java 11 自带的 HttpClient 发送一个 GET 请求,并打印状态码、响应头与响应体:
java
public static void main(String[] args) throws IOException, InterruptedException {
//创建一个httpclient的对象
HttpClient client=HttpClient.newHttpClient();
//链式调用,这个是request的对象
HttpRequest request =HttpRequest.newBuilder().uri(URI.create("https://www.sogou.com")).GET().header("User-Agent","xxxx").build();
//发送请求
// client.send();这个是同步,等到了在结束
// client.sendAsync();这个是异步,告诉你有这个事,弄完了给我
//这个里面send一旦执行就会阻塞等待
HttpResponse<String> response= client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.headers());
System.out.println(response.body());
}

十、HTTPS 加密原理
在讨论加密前,先明确几个基本概念:
- 明文:原始数据。
- 密文:加密后的数据。
- 密钥:用于加解密的"钥匙"。
- 对称加密:加密和解密使用同一个密钥("一个密钥解两边")。
- 非对称加密 :一对密钥,A 加密需 B 解密,B 加密需 A 解密;其中一把公开作为公钥 ,另一把自己保留作为私钥。
那么,如何安全地传输对称密钥呢?不可能再用一层密钥去加密密钥(无限套娃)。此时非对称加密就派上用场了。
服务器 被黑客入侵的网络设备 客户端 服务器 被黑客入侵的网络设备 客户端 #mermaid-svg-gmexvjzgT1k9yGeI{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gmexvjzgT1k9yGeI .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gmexvjzgT1k9yGeI .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gmexvjzgT1k9yGeI .error-icon{fill:#552222;}#mermaid-svg-gmexvjzgT1k9yGeI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gmexvjzgT1k9yGeI .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gmexvjzgT1k9yGeI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gmexvjzgT1k9yGeI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gmexvjzgT1k9yGeI .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gmexvjzgT1k9yGeI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gmexvjzgT1k9yGeI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gmexvjzgT1k9yGeI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gmexvjzgT1k9yGeI .marker.cross{stroke:#333333;}#mermaid-svg-gmexvjzgT1k9yGeI svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gmexvjzgT1k9yGeI p{margin:0;}#mermaid-svg-gmexvjzgT1k9yGeI .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-gmexvjzgT1k9yGeI text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-gmexvjzgT1k9yGeI .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-gmexvjzgT1k9yGeI .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-gmexvjzgT1k9yGeI .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-gmexvjzgT1k9yGeI .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-gmexvjzgT1k9yGeI #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-gmexvjzgT1k9yGeI .sequenceNumber{fill:white;}#mermaid-svg-gmexvjzgT1k9yGeI #sequencenumber{fill:#333;}#mermaid-svg-gmexvjzgT1k9yGeI #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-gmexvjzgT1k9yGeI .messageText{fill:#333;stroke:none;}#mermaid-svg-gmexvjzgT1k9yGeI .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-gmexvjzgT1k9yGeI .labelText,#mermaid-svg-gmexvjzgT1k9yGeI .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-gmexvjzgT1k9yGeI .loopText,#mermaid-svg-gmexvjzgT1k9yGeI .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-gmexvjzgT1k9yGeI .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-gmexvjzgT1k9yGeI .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-gmexvjzgT1k9yGeI .noteText,#mermaid-svg-gmexvjzgT1k9yGeI .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-gmexvjzgT1k9yGeI .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-gmexvjzgT1k9yGeI .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-gmexvjzgT1k9yGeI .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-gmexvjzgT1k9yGeI .actorPopupMenu{position:absolute;}#mermaid-svg-gmexvjzgT1k9yGeI .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-gmexvjzgT1k9yGeI .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-gmexvjzgT1k9yGeI .actor-man circle,#mermaid-svg-gmexvjzgT1k9yGeI line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-gmexvjzgT1k9yGeI :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 持有<b>公钥</b> 持有<b>私钥</b> 持有公钥 注:客户端生成对称密钥 决定密钥是 8888881密文请求(密钥是888888)(把密钥通过公钥加密)2密文请求(密钥是888888)(转发加密后的密钥)3通过私钥解密获取对称密钥是 8888884密文响应, 使用888888加密(好滴好滴)5密文响应, 使用888888加密(好滴好滴)6密文请求(对称加密)7密文请求(对称加密)8密文响应(对称加密)9密文响应(对称加密)10
HTTPS 采用"对称加密 + 非对称加密"的混合方案:如果只用非对称加密 ,效率会很低;因此我们用非对称加密来传递对称密钥,从而避开非对称加密开销大的问题。
但这种方案仍有缺陷------中间人攻击(Man-in-the-Middle):
- A:客户端;B:黑客(中间人,伪装成客户端);C:服务器。
- A → B → C:A 向 B 询问公钥。
- C → B:C 返回自己的公钥
p1。 - B 拿到公钥
p1后,自己生成一对公钥b1、私钥b2。 - B → A:把伪造的公钥
b1发给 A。 - A → B:A 用
b1加密对称密钥a1发给 B,B 成功拿到a1。 - B → C:B 用
p1把a1发给 C,并发送确认接收的消息。 - 此后双方的通信数据都被 B 窃取。
如何应对?很简单------引入数字证书。证书中包含校验和以及服务器真实的公钥;如果黑客篡改了公钥,就会导致校验和不符。而校验和是用公证机构(CA)自己的私钥签名的(完全保密),黑客只能解密却无法伪造签名(签名需要私钥)。
十一、HTTP 各版本差异对比
| 维度 | HTTP/1.0 (1996) | HTTP/1.1 (1997,当前主流) | HTTP/2 (2015) | HTTP/3 (2022) |
|---|---|---|---|---|
| 传输层 | TCP,短连接(每请求建/断连接) | TCP,持久连接 keep-alive(默认长连接) | TCP | QUIC(跑在 UDP 之上) |
| 并发模型 | 串行,队头阻塞严重 | 管线化 pipelining(仍受 TCP 队头阻塞) | 多路复用(一个连接并发多请求/响应,解决应用层队头阻塞) | 多路复用且无 TCP 队头阻塞 |
| 数据格式 | 文本 | 文本 | 二进制分帧 | 二进制(QUIC 包) |
| 头部 | 无 Host 头 | 增加 Host 头、分块传输 chunked | HPACK 头部压缩 | QPACK 头部压缩 |
| 其他 | --- | 更丰富的缓存控制 | 服务器推送(已逐步弃用) | 内置 TLS 1.3、连接迁移、0-RTT |
| 一句话 | 太慢,已淘汰 | 现在绝大多数网站还在用 | 性能大幅提升 | 彻底解决队头阻塞,但部署复杂 |
关键记忆点:HTTP/3 不是"TCP 变了",而是整个传输层换成了基于 UDP 的 QUIC;1.1→2 解决的是"一个连接里能不能并发",2→3 解决的是"TCP 本身队头阻塞"这一层。
小结
本文从 HTTP 的协议定位与抓包实战出发,系统梳理了请求/响应报文的"四段式"结构(请求行/报头/空行/正文)、GET 与 POST 的区别、URL 编码、Cookie/Session 身份机制、Referer 与 HTTPS 加密原理,并对比了各版本差异与状态码分类。掌握这些基础,是理解 Web 通信与 Java 后端开发的关键一步。