HTTP教程:超文本传输协议完整指南
本文核心要点
- HTTP是Web通信的基础协议,基于客户端-服务器模型运行
- HTTP请求由方法、路径、头部和可选正文组成
- HTTP响应包含状态码、头部和响应正文
- HTTP/2和HTTP/3在性能和安全性上有显著提升
- HTTPS通过TLS加密为HTTP提供安全传输通道
目录导航
1. 什么是HTTP协议
HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网上应用最为广泛的协议之一,它是Web浏览器和Web服务器之间进行通信的标准协议。HTTP协议定义了客户端(通常是浏览器)如何向服务器请求Web页面,以及服务器如何返回这些请求的内容。
HTTP协议最初由蒂姆-伯纳斯-李(Tim Berners-Lee)于1989年在欧洲核子研究组织(CERN)开发,1991年发布了第一个版本HTTP/0.9。1996年,HTTP/1.0正式发布,随后在1999年演变为HTTP/1.1,成为互联网历史上使用时间最长的协议版本。2015年,HTTP/2正式发布,2022年HTTP/3开始得到广泛支持。
HTTP协议的主要特点
| 特点 | 说明 |
|---|---|
| 无状态协议 | 服务器不保留之前请求的任何信息,每个请求都是独立的 |
| 客户端-服务器模型 | 客户端发起请求,服务器返回响应,两者角色明确 |
| 明文传输 | HTTP/1.1及之前版本数据以明文形式传输(HTTP/3除外) |
| 基于TCP连接 | 默认使用TCP端口80进行通信 |
| 请求-响应模式 | 采用一问一答的通信方式 |
2. HTTP工作原理
HTTP通信的基本流程可以分为以下几个步骤:
- 客户端(浏览器)建立TCP连接到服务器的80端口(HTTP)或443端口(HTTPS)
- 客户端发送HTTP请求报文到服务器
- 服务器接收请求,处理请求
- 服务器返回HTTP响应报文
- 客户端接收响应并渲染页面内容
- TCP连接关闭或保持以便后续请求复用
在这个过程中,有几个关键概念需要理解:
2.1 URL与URI的区别
URL(Uniform Resource Locator,统一资源定位符)是Web资源的完整地址,格式为:
协议://主机名:端口/路径?查询参数#锚点
示例:https://www.example.com:443/products/list?id=1001#section2
URI(Uniform Resource Identifier,统一资源标识符)是更广泛的概念,URL是URI的子集。在Web开发中,这两个术语经常混用。
2.2 TCP三次握手与HTTP
在HTTP正式通信之前,需要先建立TCP连接。这个过程需要三次握手:
客户端 --SYN--> 服务器
客户端 <--SYN-ACK-- 服务器
客户端 --ACK--> 服务器
连接建立完成
对于HTTPS,还需要额外的TLS握手过程。HTTP/2和HTTP/3通过多路复用和0-RTT恢复等技术优化了这个过程。
3. HTTP请求结构
一个完整的HTTP请求由以下部分组成:
请求方法 路径 HTTP版本
Host: example.com
User-Agent: Mozilla/5.0
Accept: text/html
Content-Type: application/json
{"username": "testuser"}
3.1 请求行
请求行包含三个元素:请求方法、请求路径和HTTP版本。
3.2 请求头部
请求头部以键值对的形式提供额外信息,常见头部包括:
| 头部名称 | 说明 | 示例 |
|---|---|---|
| Host | 目标服务器域名 | Host: www.example.com |
| User-Agent | 客户端应用程序信息 | User-Agent: Mozilla/5.0 |
| Accept | 客户端可接受的响应类型 | Accept: text/html |
| Content-Type | 请求体的数据类型 | Content-Type: application/json |
| Authorization | 认证信息 | Authorization: Bearer token123 |
| Cookie | 发送存储在客户端的Cookie | Cookie: session_id=abc123 |
3.3 请求正文
请求正文(Body)用于携带需要提交给服务器的数据。GET和HEAD请求通常不包含正文,而POST、PUT、PATCH请求通常会包含正文。
POST /api/login HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
username=admin&password=123456
4. HTTP响应结构
HTTP响应与请求结构类似,由状态行、响应头部和响应正文组成:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 1234
Cache-Control: max-age=3600
Date: Fri, 10 Apr 2026 03:00:00 GMT
<!DOCTYPE html>
<html>
<head><title>Example</title></head>
<body>...</body>
</html>
4.1 状态行
状态行包含HTTP版本、状态码和状态描述。例如:
HTTP/1.1 200 OK- 请求成功HTTP/1.1 404 Not Found- 资源不存在HTTP/1.1 500 Internal Server Error- 服务器内部错误
4.2 响应头部
响应头部提供关于响应的元信息:
| 头部名称 | 说明 | 示例 |
|---|---|---|
| Content-Type | 响应体的数据类型 | Content-Type: text/html; charset=utf-8 |
| Content-Length | 响应体的大小(字节) | Content-Length: 1234 |
| Cache-Control | 缓存控制指令 | Cache-Control: max-age=3600 |
| Set-Cookie | 设置客户端Cookie | Set-Cookie: session=abc123; HttpOnly |
| Last-Modified | 资源最后修改时间 | Last-Modified: Fri, 10 Apr 2026 00:00:00 GMT |
5. HTTP请求方法
HTTP定义了一组请求方法,用于指定对资源的操作意图:
5.1 主要请求方法一览
| 方法 | 名称 | 用途 | 是否有Body |
|---|---|---|---|
| GET | 获取资源 | 请求服务器返回指定资源 | 无 |
| POST | 提交数据 | 向服务器提交数据进行处理 | 有 |
| PUT | 完整更新 | 用新数据完全替换资源 | 有 |
| DELETE | 删除资源 | 请求服务器删除指定资源 | 可有可无 |
| PATCH | 部分更新 | 对资源进行部分修改 | 有 |
| HEAD | 获取头部 | 仅获取资源的响应头部 | 无 |
| 查询选项 | 查询服务器支持的请求方法 | 无 |
5.2 GET与POST的核心区别
GET 方法
用于获取数据,参数暴露在URL中
URL长度受限(浏览器通常限制约2048字符)
请求可以被浏览器缓存
参数保留在浏览器历史记录中
适合查询、搜索等只读操作
POST 方法
用于提交数据,参数在请求体中
无URL长度限制(理论上无限制)
请求默认不被缓存
参数不会保存在浏览器历史记录
适合提交表单、上传文件等写操作
- GET /users - 获取用户列表
- GET /users/123 - 获取ID为123的用户
- POST /users - 创建新用户
- PUT /users/123 - 完整更新ID为123的用户
- PATCH /users/123 - 部分更新ID为123的用户
- DELETE /users/123 - 删除ID为123的用户
6. HTTP状态码详解
HTTP状态码是服务器对请求处理结果的数字表示,由三位数字组成,分为五个类别:
6.1 1xx 信息性状态码
表示请求已被服务器接收,继续处理。
| 状态码 | 名称 | 说明 |
|---|---|---|
| 100 | Continue | 服务器收到请求的起始部分,客户端应继续发送 |
| 101 | Switching Protocols | 服务器同意切换协议(如切换到WebSocket) |
6.2 2xx 成功状态码
表示请求已成功被服务器接收、理解并处理。
| 状态码 | 名称 | 说明 |
|---|---|---|
| 200 | OK | 请求成功,默认GET请求成功 |
| 201 | Created | 资源创建成功,常用于POST请求 |
| 204 | No Content | 请求成功但响应体为空 |
6.3 3xx 重定向状态码
表示需要进一步操作才能完成请求。
| 状态码 | 名称 | 说明 |
|---|---|---|
| 301 | Moved Permanently | 资源永久移动到新位置,搜索引擎会更新索引 |
| 302 | Found | 临时移动,后续请求仍使用原URL |
| 304 | Not Modified | 资源未修改,使用缓存版本 |
| 307 | Temporary Redirect | 临时重定向,与302类似但保持请求方法 |
6.4 4xx 客户端错误状态码
表示请求包含语法错误或无法被服务器理解和处理。
| 状态码 | 名称 | 说明 |
|---|---|---|
| 400 | Bad Request | 请求语法错误或参数无效 |
| 401 | Unauthorized | 需要认证或认证失败 |
| 403 | Forbidden | 服务器拒绝访问,无权限 |
| 404 | Not Found | 请求的资源不存在 |
| 405 | Method Not Allowed | 请求方法不被支持 |
| 429 | Too Many Requests | 请求频率超限,触发速率限制 |
6.5 5xx 服务器错误状态码
表示服务器在处理请求时发生内部错误。
| 状态码 | 名称 | 说明 |
|---|---|---|
| 500 | Internal Server Error | 服务器内部错误,代码异常 |
| 502 | Bad Gateway | 网关或代理服务器收到无效响应 |
| 503 | Service Unavailable | 服务暂时不可用,可能过载或维护中 |
| 504 | Gateway Timeout | 网关或代理服务器等待上游响应超时 |
7. 常见HTTP头部
HTTP头部是请求和响应中非常重要的组成部分,它们提供了关于消息、元数据、条件请求和安全等方面的信息。
7.1 通用头部
通用头部同时适用于请求和响应消息:
| 头部 | 说明 |
|---|---|
| Date | 消息产生的日期和时间 |
| Cache-Control | 指定缓存机制 directives |
| Connection | 控制连接是否保持打开(Keep-Alive或Close) |
| Transfer-Encoding | 消息体的传输编码方式(如chunked) |
7.2 请求头部
| 头部 | 说明 |
|---|---|
| Accept | 客户端可处理的媒体类型 |
| Accept-Encoding | 客户端支持的内容编码(gzip、deflate等) |
| Accept-Language | 客户端期望的语言 |
| If-Modified-Since | 条件请求,资源在此日期后修改才返回 |
| If-None-Match | 条件请求,资源的ETag值不匹配才返回 |
| Referer | 请求的来源页面URL |
| Origin | 跨域请求的来源(用于CORS) |
7.3 响应头部
| 头部 | 说明 |
|---|---|
| Content-Type | 响应体的MIME类型 |
| Content-Encoding | 响应体的编码方式(如gzip) |
| ETag | 资源的版本标识符 |
| Last-Modified | 资源最后修改时间 |
| Access-Control-Allow-Origin | CORS允许的来源(跨域资源共享) |
| Strict-Transport-Security | 强制使用HTTPS连接(HSTS) |
8. HTTP版本演进
HTTP协议经历了多个版本的迭代,每个版本都在性能和特性上有显著提升。
8.1 HTTP/1.0 vs HTTP/1.1
HTTP/1.1是互联网历史上使用最广泛的协议版本,相比HTTP/1.0的主要改进:
- 持久连接(Keep-Alive):默认开启,TCP连接可复用,避免重复三次握手
- 管道化(Pipelining):客户端可以发送多个请求而无需等待响应
- 分块传输编码:支持流式响应,无需预先知道内容长度
- 新增缓存控制头部:更精细的缓存管理
- 新增请求方法:OPTIONS、PUT、DELETE等
8.2 HTTP/1.1 vs HTTP/2
HTTP/2在2015年发布,主要改进:
二进制分帧
HTTP/2将消息分解为更小的帧,以二进制格式传输。相比文本格式,二进制解析更高效、更不易出错。
多路复用
单个TCP连接上可以并行传输多个请求和响应,无需按顺序等待。彻底解决了HTTP/1.1的队头阻塞问题。
服务器推送
服务器可以主动向客户端推送资源,无需客户端明确请求。适合推送CSS、JS等确定性资源。
Header压缩
使用HPACK算法压缩请求和响应头部,减少传输开销。
8.3 HTTP/2 vs HTTP/3
HTTP/3在2022年成为RFC 9114标准,核心变化是使用QUIC协议替代TCP:
| 特性 | HTTP/2 | HTTP/3 |
|---|---|---|
| 传输层 | TCP | QUIC(基于UDP) |
| 队头阻塞 | 存在(TCP级别) | 无(QUIC级别) |
| 连接建立 | TCP + TLS 1.2 = 2-3 RTT | QUIC + 0-RTT恢复 = 0-1 RTT |
| 连接迁移 | 不支持(IP变化需重建) | 支持(连接ID机制) |
| 头部压缩 | HPACK | QPACK(专为QUIC优化) |
9. HTTPS与安全
HTTP协议在设计时未考虑安全性,数据以明文传输,存在被窃听、篡改和伪装的风险。HTTPS通过在HTTP和TCP之间添加TLS(Transport Layer Security)层来解决这个问题。
9.1 HTTPS工作原理
HTTPS的核心是TLS加密,其工作流程:
1. 客户端Hello
- 客户端支持的TLS版本
- 支持的加密套件列表
- 客户端随机数
2. 服务器Hello
- 服务器选择的TLS版本和加密套件
- 服务器证书(包含公钥)
- 服务器随机数
3. 密钥交换
- 客户端验证证书
- 生成预主密钥
- 使用服务器公钥加密后发送
4. 生成会话密钥
- 双方使用随机数和预主密钥
- 计算生成会话密钥(对称加密密钥)
5. 加密通信开始
- 使用会话密钥进行对称加密通信
9.2 SSL/TLS证书
SSL/TLS证书用于证明服务器身份,由受信任的证书颁发机构(CA)签发:
| 证书类型 | 验证级别 | 显示效果 |
|---|---|---|
| DV(域名验证) | 仅验证域名所有权 | 地址栏显示锁图标 |
| OV(组织验证) | 验证域名和组织信息 | 显示组织名称 |
| EV(扩展验证) | 最严格的验证流程 | 绿色地址栏 + 组织名称 |
9.3 HTTPS的SEO优势
Google已明确将HTTPS作为排名信号之一。使用HTTPS的优势:
- 搜索排名提升(Google明确表示HTTPS是轻量级排名因素)
- 防止流量劫持和广告注入
- 保护用户隐私和数据安全
- 支持HTTP/2和HTTP/3(现代浏览器要求)
- 增强用户信任度(浏览器地址栏显示安全标识)
10. HTTP缓存机制
HTTP缓存是提升Web性能的核心技术,通过将响应内容存储在客户端或中间节点,减少重复请求,加快页面加载速度。
10.1 缓存策略
| 策略 | 说明 | 适用场景 |
|---|---|---|
| 强缓存 | Expires或Cache-Control控制,直接使用缓存不发送请求 | 静态资源(CSS、JS、图片等) |
| 协商缓存 | Last-Modified/ETag控制,需发送请求验证资源是否更新 | 可能变化的资源 |
| 不缓存 | Cache-Control: no-store,强制每次从服务器获取 | 敏感数据、实时数据 |
10.2 Cache-Control常用指令
Cache-Control: max-age=3600 # 缓存有效期3600秒
Cache-Control: no-cache # 每次使用前需验证
Cache-Control: no-store # 不缓存任何内容
Cache-Control: private # 仅客户端可缓存
Cache-Control: public # 可被任何节点缓存
Cache-Control: must-revalidate # 缓存过期后必须验证
10.3 缓存判断流程
客户端发起请求
|
v
检查缓存
|
是否有缓存?---否---> 向服务器发送请求
|
是
v
是否过期?---否---> 直接返回缓存(可能更新头部)
|
是
v
添加条件请求头(If-Modified-Since 或 If-None-Match)
|
v
服务器响应:304 Not Modified --- > 返回缓存(节省流量)
|
200 OK
v
更新缓存,返回新内容
11. 实际应用示例
11.1 使用curl发送HTTP请求
# GET请求
curl https://api.example.com/users
# POST请求(JSON数据)
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name": "张三", "email": "zhangsan@example.com"}'
# 带认证的请求
curl -H "Authorization: Bearer your_token_here" \
https://api.example.com/profile
# 下载文件并保存
curl -O https://example.com/file.zip
# 查看响应头
curl -I https://example.com
11.2 Fetch API示例(JavaScript)
// GET请求
fetch('https://api.example.com/users')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
// POST请求
fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer your_token_here'
},
body: JSON.stringify({ name: '张三', email: 'zhangsan@example.com' })
})
.then(response => response.json())
.then(data => console.log('Created:', data))
.catch(error => console.error('Error:', error));
// Async/Await写法
async function getUsers() {
try {
const response = await fetch('https://api.example.com/users');
const data = await response.json();
return data;
} catch (error) {
console.error('Failed:', error);
}
}
11.3 HTTP调试技巧
- 浏览器开发者工具:Network面板查看所有网络请求的详情
- Postman:功能强大的API测试工具,支持各种HTTP方法和认证
- curl:命令行工具,适合脚本化和快速测试
- Charles/Fiddler:抓包工具,可查看和修改所有HTTP流量
12. 相关工具推荐
相关教程
- TCP/IP协议入门 - 了解HTTP依赖的传输层协议
- HTTPS协议详解 - 深入了解TLS加密原理
- WebSocket vs HTTP对比 - 了解两种通信方式的优劣
- HTTP/3与QUIC协议 - 了解最新HTTP协议标准