1. HTTP的定义与核心属性
HTTP(HyperText Transfer Protocol,超文本传输协议)是万维网(WWW)的核心通信协议,定义了客户端(如浏览器、APP)与服务器之间如何传输“超文本”(包括HTML、图片、JSON、视频等资源)的规则。它基于TCP/IP协议栈工作,是一种应用层协议,其设计目标是实现“简单、可扩展、无状态”的通信。
HTTP的两大核心属性决定了其底层逻辑:
- 无状态(Stateless):服务器不会记录客户端的历史请求信息。例如,用户第一次访问某网站时登录,第二次访问时服务器仍需重新验证身份——这是为了简化服务器设计、提高并发处理能力,但也带来了“会话维持”的需求(后续通过Cookie、Session补充)。
- 无连接(Connectionless,早期特性):HTTP/1.0及之前,每次请求-响应后都会关闭TCP连接。这导致频繁请求时“三次握手”“四次挥手”的开销过大,因此HTTP/1.1引入了
Keep-Alive
长连接,允许同一TCP连接处理多个请求。
2. HTTP的发展历程:从0.9到3.0的演进
HTTP自1989年由蒂姆·伯纳斯-李(Tim Berners-Lee)设计以来,经历了多次版本迭代,核心目标是优化性能、提升安全性、扩展功能。
版本 | 发布时间 | 核心改进 |
---|---|---|
HTTP/0.9 | 1991年 | 极简设计:仅支持GET 方法,无请求头/响应头,响应内容仅为纯HTML文本,无状态码。 |
HTTP/1.0 | 1996年 | 1. 新增POST /HEAD 方法;2. 引入请求头(如 User-Agent )和响应头;3. 支持多种媒体类型(图片、音频等); 4. 新增状态码(如200、404)。 |
HTTP/1.1 | 1999年 | 1. 支持Keep-Alive 长连接(默认开启);2. 引入“管线化”(Pipelining,允许同时发送多个请求); 3. 新增 PUT /DELETE /OPTIONS 方法;4. 支持虚拟主机( Host 头)、分块传输(Transfer-Encoding: chunked )。 |
HTTP/2 | 2015年 | 1. 采用二进制帧(替代HTTP/1.x的文本格式),减少解析开销; 2. 实现多路复用(同一TCP连接中并行处理多个请求,解决HTTP/1.1的“队头阻塞”); 3. 支持服务器推送(Server Push,主动向客户端发送依赖资源,如HTML引用的CSS); 4. 头部压缩(HPACK算法,减少重复头信息传输)。 |
HTTP/3 | 2022年 | 1. 基于QUIC协议(而非TCP),使用UDP实现可靠传输; 2. 彻底解决“队头阻塞”(TCP是连接级阻塞,QUIC是流级阻塞); 3. 更快的连接建立(0-RTT/1-RTT握手,无需TCP三次握手); 4. 原生支持加密(基于TLS 1.3)。 |
当前主流应用仍以HTTP/1.1和HTTP/2为主,HTTP/3正逐步普及(如Chrome、Cloudflare已支持),其核心优势是在高延迟网络(如移动网络)中大幅提升速度。
3. HTTP的工作流程:从“输入URL”到“页面显示”
当用户在浏览器中输入https://www.example.com
(注:实际是HTTPS,此处以HTTP逻辑为例)并按下回车,整个HTTP通信流程可分为7个步骤:
步骤1:URL解析与DNS查询
浏览器首先解析URL,提取核心信息:
- 协议:HTTP/HTTPS;
- 域名:
www.example.com
; - 端口:HTTP默认80,HTTPS默认443(若URL未指定则用默认);
- 路径:如
/index.html
(默认路径为/
)。
随后,浏览器通过DNS查询将域名转换为服务器的IP地址(如192.168.1.1
):先查本地DNS缓存,若未命中则向根DNS、顶级域DNS(.com)、权威DNS逐层查询,最终获取IP。
步骤2:建立TCP连接(HTTP/1.x/2)
HTTP基于TCP实现可靠传输,因此需先完成TCP三次握手:
- 客户端向服务器发送
SYN
包,请求建立连接; - 服务器返回
SYN+ACK
包,确认请求并同步序列号; - 客户端返回
ACK
包,连接正式建立。
若为HTTP/3,则跳过TCP握手,直接通过QUIC协议建立UDP连接(仅需1-RTT甚至0-RTT,速度更快)。
步骤3:发送HTTP请求
连接建立后,客户端向服务器发送HTTP请求,请求格式由“请求行 + 请求头 + 空行 + 请求体”四部分组成(示例如下):
POST /login HTTP/1.1 # 请求行:方法 + 路径 + 版本
Host: www.example.com # 请求头:Host(指定虚拟主机)
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/112.0.0.0 # 客户端信息
Content-Type: application/json # 请求体数据类型
Content-Length: 45 # 请求体长度
Cookie: sessionid=abc123 # 客户端会话信息(解决无状态){"username": "test", "password": "123456"} # 请求体(仅POST/PUT等方法有)
步骤4:服务器处理请求
服务器(如Nginx、Apache、Tomcat)接收请求后,按以下逻辑处理:
- 解析请求行:确认HTTP版本、请求方法、目标路径;
- 解析请求头:获取客户端信息、Cookie、数据类型等;
- 处理业务逻辑:如查询数据库、验证用户身份(由后端程序如Java/Python实现);
- 构建响应数据:生成HTML、JSON等响应内容。
步骤5:返回HTTP响应
服务器处理完成后,向客户端返回HTTP响应,格式为“状态行 + 响应头 + 空行 + 响应体”(示例如下):
HTTP/1.1 200 OK # 状态行:版本 + 状态码 + 原因短语
Server: Nginx # 服务器软件
Content-Type: text/html; charset=utf-8 # 响应体类型
Content-Length: 1024 # 响应体长度
Set-Cookie: token=def456; Path=/ # 服务器向客户端设置Cookie<!DOCTYPE html> # 响应体:HTML内容
<html><head><title>首页</title></head><body>欢迎访问!</body>
</html>
步骤6:关闭TCP连接(或复用)
- 若为HTTP/1.0(无
Keep-Alive
):响应完成后立即执行TCP四次挥手关闭连接; - 若为HTTP/1.1(默认
Keep-Alive
):连接会保持一段时间(由Keep-Alive: timeout=5
指定),期间可复用处理后续请求; - 若为HTTP/2/3:连接默认长期复用,通过多路复用处理多个请求。
步骤7:浏览器渲染响应体
客户端接收响应后,若响应体是HTML,浏览器会按“解析HTML→构建DOM树→解析CSS→构建CSSOM树→合成渲染树→布局→绘制”的流程渲染页面,最终显示给用户。
4. HTTP核心组件:方法、状态码与头字段
4.1 HTTP请求方法:定义“客户端想做什么”
HTTP方法规定了客户端对服务器资源的操作类型,核心方法及语义如下:
方法 | 语义 | 幂等性(多次请求结果一致) | 安全性(不修改服务器资源) | 常见场景 |
---|---|---|---|---|
GET | 获取资源 | 是 | 是 | 访问页面、查询数据(如/user?id=1 ) |
POST | 提交资源(创建/修改) | 否 | 否 | 登录、上传文件、提交表单 |
PUT | 全量更新资源 | 是 | 否 | 修改用户信息(如/user/1 ,覆盖全字段) |
DELETE | 删除资源 | 是 | 否 | 删除数据(如/user/1 ) |
HEAD | 获取资源头部(无体) | 是 | 是 | 检查资源是否存在(如文件大小) |
OPTIONS | 询问服务器支持的方法 | 是 | 是 | CORS预检请求(跨域时) |
PATCH | 部分更新资源 | 是 | 否 | 修改用户昵称(仅传nickname 字段) |
关键区别:GET
请求的参数会拼在URL中(如/search?keyword=test
),长度有限且暴露隐私;POST
参数在请求体中,更安全且支持大数据传输。
4.2 HTTP状态码:定义“服务器的处理结果”
状态码是服务器返回的3位数字,用于告知客户端请求的处理状态,分为5大类:
1xx 信息性状态码(临时响应)
- 100 Continue:服务器已接收请求头,客户端可继续发送请求体(常用于大文件上传)。
2xx 成功状态码(请求已处理)
- 200 OK:请求成功,响应体为资源内容(最常见状态码);
- 204 No Content:请求成功,但无响应体(如DELETE删除成功);
- 206 Partial Content:部分请求成功(用于断点续传,如视频分片下载)。
3xx 重定向状态码(需进一步操作)
- 301 Moved Permanently:资源永久迁移,浏览器会缓存新地址(如旧域名跳转新域名);
- 302 Found:资源临时迁移,不缓存新地址(如登录后跳转首页);
- 304 Not Modified:资源未修改,客户端直接使用本地缓存(关键缓存状态码);
- 307 Temporary Redirect:与302类似,但严格保持请求方法(如POST不会转为GET)。
4xx 客户端错误状态码(请求有误)
- 400 Bad Request:请求格式错误(如JSON语法错误);
- 401 Unauthorized:请求未授权(需登录,响应头会提示认证方式);
- 403 Forbidden:请求已授权,但无访问权限(如普通用户访问管理员页面);
- 404 Not Found:资源不存在(最常见错误,如URL路径错误);
- 405 Method Not Allowed:请求方法不支持(如用GET访问仅支持POST的接口)。
5xx 服务器错误状态码(服务器故障)
- 500 Internal Server Error:服务器内部错误(如代码bug、数据库崩溃);
- 502 Bad Gateway:网关错误(如Nginx反向代理时,后端服务器无响应);
- 503 Service Unavailable:服务器暂时不可用(如维护中,通常会返回
Retry-After
头告知重试时间); - 504 Gateway Timeout:网关超时(后端服务器处理时间过长)。
4.3 HTTP头字段:传递“额外元信息”
头字段是请求/响应中键值对的集合,用于传递客户端、服务器、资源的元信息,核心头字段分类如下:
- 通用头:请求和响应都可使用,如
Date
(时间)、Cache-Control
(缓存控制); - 请求头:仅客户端发送,如
User-Agent
(客户端标识)、Cookie
(会话信息)、Accept
(可接收的媒体类型); - 响应头:仅服务器发送,如
Server
(服务器标识)、Set-Cookie
(设置Cookie)、Location
(重定向地址); - 实体头:描述请求体/响应体,如
Content-Type
(数据类型)、Content-Length
(数据长度)、ETag
(资源指纹)。
5. HTTP的核心痛点与优化:缓存、安全与跨域
5.1 HTTP缓存:提升性能的关键
HTTP缓存是减少重复请求、降低服务器压力、加快页面加载的核心机制,分为强缓存和协商缓存:
强缓存(本地缓存,无需发请求)
由Cache-Control
或Expires
头控制:
Cache-Control: max-age=3600
:资源在本地缓存3600秒(1小时),期间无需请求服务器;Expires: Wed, 29 Aug 2025 12:00:00 GMT
:HTTP/1.0的缓存头,指定资源过期时间(优先级低于Cache-Control
)。
若缓存未过期,浏览器直接使用本地资源,控制台会显示“200 OK (from disk cache)”。
协商缓存(需发请求,验证资源是否更新)
若强缓存过期,客户端会发送请求到服务器,通过以下头字段验证资源是否变化:
- Last-Modified + If-Modified-Since:基于资源修改时间。服务器返回
Last-Modified: Wed, 28 Aug 2024 10:00:00 GMT
,客户端下次请求时携带If-Modified-Since: 相同时间
,服务器若判断资源未修改则返回304; - ETag + If-None-Match:基于资源内容指纹(如MD5)。服务器返回
ETag: "abc123"
,客户端下次请求携带If-None-Match: "abc123"
,服务器若指纹一致则返回304(优先级高于时间验证,避免“修改时间变但内容不变”的误判)。
5.2 HTTP的安全缺陷与HTTPS
HTTP的核心安全问题是明文传输:请求/响应内容在网络中以文本形式传输,可被中间人窃听(如获取密码)、篡改(如修改支付金额)、伪造(如冒充服务器)。
为解决此问题,HTTPS(HTTP Secure)应运而生:在HTTP与TCP之间增加TLS/SSL加密层,实现三大安全目标:
- 机密性:通过对称加密(如AES)加密数据,仅客户端和服务器有密钥;
- 完整性:通过哈希算法(如SHA-256)验证数据,防止篡改;
- 身份认证:通过CA证书验证服务器身份,防止伪造。
HTTPS已成为当前Web的标配,所有涉及隐私(如登录、支付)的场景必须使用。
5.3 跨域与CORS:HTTP的跨源通信方案
由于浏览器的“同源策略”(协议、域名、端口三者一致为同源),非同源的客户端无法直接访问服务器资源(如http://a.com
的页面无法请求http://b.com
的接口),这就是跨域问题。
HTTP通过CORS(跨域资源共享) 机制解决跨域,核心是服务器返回特定响应头,允许客户端跨域访问:
Access-Control-Allow-Origin: http://a.com
:允许a.com
的跨域请求(*
表示允许所有域名);Access-Control-Allow-Methods: GET, POST, PUT
:允许的请求方法;Access-Control-Allow-Credentials: true
:允许客户端携带Cookie跨域;Access-Control-Allow-Headers: Content-Type
:允许的自定义请求头。
对于“非简单请求”(如POST请求的Content-Type: application/json
),客户端会先发送OPTIONS预检请求,确认服务器允许跨域后再发送真实请求。