什么是http?
定义:http: 是 HTTP 是一种基于 TCP
的超文本传输协议,用于客户端与服务器之间的请求与响应,是互联网上最常用的 网络协议
。
** HTTP 工作原理**
HTTP 协议规定了客户端如何请求网页以及服务器如何响应,通信过程以请求报文和响应报文进行。
HTTP 的特点和缺点
-
无连接(Connectionless)
- HTTP/1.0 行为:每个请求/响应周期后关闭 TCP 连接,多次请求需重复建立连接,效率低下。
- HTTP/1.1 改进:默认启用持久连接(
Connection: keep-alive
),单个 TCP 连接可处理多个请求,减少延迟。 - 核心逻辑:协议本身不强制保持长期连接状态,由服务器和客户端协商管理。
-
无状态(Stateless)
- 定义:服务器不保存客户端上下文信息,每个请求独立处理。
- 优点:简化服务端设计,降低内存占用,适合高并发场景。
- 缺点:需额外机制(如 Cookie、Session、Token)实现有状态业务逻辑(如登录态)。
-
灵活可扩展(Flexible)
- 内容类型支持:通过
Content-Type
标头(如text/html
,application/json
)标记任意数据类型。 - 方法扩展性:支持 GET、POST 等基础方法,允许自定义方法(如 WebDAV 的
PROPFIND
)。 - 协议演进:从 HTTP/1.0 到 HTTP/3,持续引入新特性(如多路复用、头部压缩、QUIC 协议)。
- 内容类型支持:通过
-
简单快速(Simple & Efficient)
- 请求格式:基于纯文本的请求行(如
GET /path HTTP/1.1
),易于调试和扩展。 - 轻量级交互:早期设计注重减少协议开销,但头部重复和未压缩问题在 HTTP/2 前影响性能。
HTTP 的缺点
-
无状态的双刃剑
- 业务复杂性:需通过 Cookie 等机制“模拟”状态,增加开发成本和安全风险(如 CSRF 攻击)。
- 重复传输:每次请求需携带完整身份信息(如 Cookie),导致冗余流量。
-
明文传输的不安全性
- HTTP 明文风险:请求头、响应头、内容均未加密,易被窃听(如密码泄露)、篡改(如广告注入)、伪装(如钓鱼网站)。
- HTTPS 解决方案:通过 TLS/SSL 加密传输,解决窃听、篡改、伪装问题,成为现代 Web 标准。
-
队头阻塞(Head-of-Line Blocking)
- HTTP/1.1 问题:同一 TCP 连接中,请求必须按顺序处理,前序请求延迟会阻塞后续请求。
- HTTP/2 优化:引入多路复用(Multiplexing),支持并发处理请求,但 TCP 层仍可能因丢包导致阻塞。
- HTTP/3 革新:基于 QUIC 协议(UDP 实现),彻底解决传输层队头阻塞。
- 性能瓶颈(HTTP/1.x)
- 连接数限制:浏览器对同一域名限制 TCP 连接数(如 6 个),导致高延迟场景下资源加载排队。
- 头部冗余:未压缩的重复头部(如
User-Agent
)浪费带宽,HTTP/2 引入 HPACK 压缩算法优化。
HTTP 请求/响应的步骤
1. 客户端连接到 Web 服务器
- TCP 三次握手:建立客户端与服务器之间的 TCP 连接。
- HTTP 版本差异:
- HTTP/1.0:默认短连接,每次请求后关闭连接。
- HTTP/1.1+:默认持久连接(
Connection: keep-alive
),可复用 TCP 连接处理多个请求。
2. 发送 HTTP 请求
- 请求报文构造:按协议格式生成请求行、请求头、空行、请求体。
- 关键细节:
- 浏览器自动附加默认头(如
Host
,User-Agent
)。 - 携带必要信息(如 Cookie、认证令牌)。
- 浏览器自动附加默认头(如
3. 服务器处理请求并返回响应
- 处理流程:
- 解析请求头,验证权限(如
Authorization
)。 - 路由到后端服务或读取静态资源。
- 构造响应报文(状态行、响应头、空行、响应体)。
- 解析请求头,验证权限(如
- 缓存机制:根据请求头(如
If-Modified-Since
)返回304 Not Modified
。
4. 释放 TCP 连接(条件性)
- 短连接:HTTP/1.0 默认关闭连接。
- 持久连接:HTTP/1.1+ 保持连接复用,超时或主动关闭时释放。
5. 客户端解析内容
- HTML 渲染:解析 HTML/CSS/JS,加载子资源(如图片、脚本)。
- 关键过程:
- 根据
Content-Type
解码响应体(如gzip
解压)。 - 执行客户端逻辑(如 JavaScript 事件处理)。
- 根据
请求的 HTTP 协议格式
- 请求报文:
GET请求
GET /path?query=1 HTTP/1.1 // 请求行:方法 + 请求URI + 协议版本
Host: example.com // 必需头,请求的目标域名和端口号(HTTP/1.1+)
Origin:http://localhost:8081/ // 必需头,请求的源站信息(跨域请求时需携带)
User-Agent: Mozilla/5.0 // 浏览器信息
Accept: text/html // 客户端可接受的响应类型
Cookie: name=value // 当前域名下的 Cookie
Content-Type: application/json // 请求体类型(POST/PUT 时需指定)
// 空行(CRLF)
{"key": "value"} // 请求体(可选)
POST请求
请求字段详解
Header | 解释 | 示例 |
---|---|---|
Accept | 指定客户端能够接收的内容类型 | Accept: text/plain, text/html |
Accept-Charset | 浏览器可以接受的字符编码集 | Accept-Charset: iso-8859-5 |
Accept-Encoding | 指定浏览器可以支持的服务器返回内容压缩编码类型 | Accept-Encoding: compress, gzip |
Accept-Language | 浏览器可接受的语言 | Accept-Language: en,zh |
Accept-Ranges | 可以请求网页实体的一个或多个子范围字段 | Accept-Ranges: bytes |
Authorization | HTTP 授权的授权证书 | Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Cache-Control | 指定请求和响应遵循的缓存机制 | Cache-Control: no-cache |
Connection | 表示是否需要持久连接(HTTP 1.1 默认进行持久连接) | Connection: close |
Cookie | 请求发送时,附带当前域名下的所有 Cookie | Cookie: $Version=1; Skin=new; |
Content-Length | 请求的内容长度 | Content-Length: 348 |
Content-Type | 请求的实体对应的 MIME 类型 | Content-Type: application/x-www-form-urlencoded |
Date | 请求发送的日期和时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
Expect | 请求的特定服务器行为 | Expect: 100-continue |
From | 发出请求用户的 Email | From: user@email.com |
Host | 指定请求服务器的域名和端口号 | Host: www.zcmhi.com |
If-Match | 请求内容与实体匹配时才有效 | If-Match: "737060cd8c284d8af7ad3082f209582d" |
If-Modified-Since | 仅在内容自指定时间后被修改才会返回;否则返回 304 | If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
If-None-Match | 如果内容未改变则返回 304,使用之前的 ETag 进行判断 | If-None-Match: "737060cd8c284d8af7ad3082f209582d" |
If-Range | 实体未改变时发送部分内容,否则发送整个实体 | If-Range: "737060cd8c284d8af7ad3082f209582d" |
If-Unmodified-Since | 仅在内容自指定时间后未被修改才请求成功 | If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
Max-Forwards | 限制请求经过代理/网关的最大传输次数 | Max-Forwards: 10 |
Pragma | 包含实现特定的指令 | Pragma: no-cache |
Proxy-Authorization | 连接代理服务器的授权证书 | Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Range | 请求实体的部分内容,指定字节范围 | Range: bytes=500-999 |
Referer | 请求来源页面的地址(即“来路”) | Referer: www.zcmhi.com/archives/71… |
TE | 客户端愿意接受的传输编码及尾部头信息 | TE: trailers,deflate;q=0.5 |
Upgrade | 指定希望升级的协议 | Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 |
User-Agent | 发出请求的客户端信息 | User-Agent: Mozilla/5.0 (Linux; X11) |
Via | 通知中间网关或代理服务器地址及协议版本 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning | 关于消息实体的警告信息 | Warn: 199 Miscellaneous warning |
- 响应报文:
HTTP/1.1 200 OK // 状态行:协议版本 + 状态码 + 原因短语
Content-Type: text/html // 响应体类型
Cache-Control: max-age=3600 // 缓存控制
Set-Cookie: name=value // 设置 Cookie
ETag: "abc123" // 资源版本标识
// 空行(CRLF)
<!DOCTYPE html>...</html> // 响应体
响应字段详解
Header | 解释 | 示例 |
---|---|---|
Accept-Ranges | 表明服务器是否支持范围请求及其类型 | Accept-Ranges: bytes |
Age | 原始服务器到代理缓存形成的估算时间(秒) | Age: 12 |
Allow | 指定资源可接受的请求方法,不允许则返回 405 | Allow: GET, HEAD |
Cache-Control | 缓存控制策略,是否可缓存及缓存类型 | Cache-Control: no-cache |
Content-Encoding | 服务器支持的压缩编码类型 | Content-Encoding: gzip |
Content-Language | 响应体所使用的语言 | Content-Language: en,zh |
Content-Length | 响应体的字节长度 | Content-Length: 348 |
Content-Location | 响应资源的备选位置 | Content-Location: /index.htm |
Content-MD5 | 响应体的 MD5 校验值 | Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ== |
Content-Range | 响应体中返回部分数据的字节位置 | Content-Range: bytes 21010-47021/47022 |
Content-Type | 响应内容的 MIME 类型 | Content-Type: text/html; charset=utf-8 |
Date | 响应生成时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
ETag | 实体标签值,用于缓存和比较 | ETag: "737060cd8c284d8af7ad3082f209582d" |
Expires | 响应过期的日期和时间 | Expires: Thu, 01 Dec 2010 16:00:00 GMT |
Last-Modified | 响应资源的最后修改时间 | Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT |
Location | 重定向地址或新资源位置 | Location: www.zcmhi.com/archives/94… |
Pragma | 实现特定的指令,适用于整个响应链 | Pragma: no-cache |
Proxy-Authenticate | 认证方案,适用于代理服务器 | Proxy-Authenticate: Basic |
Refresh | 网页重定向(非标准头,由浏览器支持) | Refresh: 5; url=www.zcmhi.com/archives/94… |
Retry-After | 暂不可用时建议客户端重试的等待时间(秒) | Retry-After: 120 |
Server | 响应服务器的软件名称 | Server: Apache/1.3.27 (Unix) (Red-Hat/Linux) |
Set-Cookie | 设置 Cookie 值到客户端 | Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1 |
Trailer | 在分块传输结束后附加的头信息 | Trailer: Max-Forwards |
Transfer-Encoding | 响应内容的传输编码方式 | Transfer-Encoding: chunked |
Vary | 告知缓存是否使用该响应或向服务器重新请求 | Vary: * |
Via | 显示响应经过的中间代理服务器链路 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning | 关于响应体可能存在的问题的警告信息 | Warning: 199 Miscellaneous warning |
WWW-Authenticate | 指定客户端应使用的认证方式 | WWW-Authenticate: Basic |
HTTP 方法
方法 | 幂等性 | 安全性 | REST 语义 | 典型场景 |
---|---|---|---|---|
GET | 是 | 是 | 资源检索 | 获取用户信息 |
POST | 否 | 否 | 创建子资源 | 提交订单表单 |
PUT | 是 | 否 | 全量更新资源 | 修改用户个人资料 |
PATCH | 否 | 否 | 部分更新资源 | 修改用户邮箱地址 |
DELETE | 是 | 否 | 删除资源 | 移除商品收藏 |
HEAD | 是 | 是 | 获取元数据 | 检查资源是否存在 |
请求响应状态码
分类 | 范围 | 说明 | 典型状态码 |
---|---|---|---|
1xx | 100-199 | 信息响应 | 100 Continue(大文件上传预处理) |
2xx | 200-299 | 成功响应 | 201 Created(资源创建成功) |
3xx | 300-399 | 重定向 | 304 Not Modified(协商缓存生效) |
4xx | 400-499 | 客户端错误 | 429 Too Many Requests(限流触发) |
5xx | 500-599 | 服务器错误 | 503 Service Unavailable(熔断状态) |
GET 与 POST 区别
特性 | GET | POST |
---|---|---|
语义 | 获取资源(幂等) | 提交数据(非幂等) |
参数位置 | URL 查询字符串(?key=value ) | 请求体(支持多种编码格式) |
长度限制 | 由浏览器/服务器限制(非协议限制) | 无协议限制,受服务器配置约束 |
安全性 | URL 暴露参数(即使 HTTPS 也会被记录日志) | 参数在请求体中(HTTPS 下加密传输) |
缓存 | 可被浏览器、代理服务器缓存 | 默认不缓存(需显式设置 Cache-Control ) |
历史记录 | 参数保留在浏览器历史 | 参数不保留 |
编码类型 | 仅 application/x-www-form-urlencoded | 支持多种(如 multipart/form-data ) |
数据操作类型 | 查询(按 REST 规范) | 创建/更新(按 REST 规范) |
TCP 数据包 | 单次发送(请求头+查询参数) | 分两次发送(先头,后体) |
HTTPS
https 的基本概念
https:是在 HTTP 下 加入 SSL/TLS 层进行加密传输的协议。
http 和 https 的区别?
- 安全性:http 明文传输,https 是 ssl 加密传输协议。
- 证书与身份验证:Https 协议需要 CA 证书,费用较高。
- 端口与协议层:http 的默认端口为 80,工作在应用层,基于 TCP 协议。https 的端口为 443 在传输层和应用层之间加入 SSL/TLS 协议,形成加密通道(TLS 更安全是主流)
- 性能与成本:http 的连接很简单,是无状态的。HTTPS 因加密/解密过程增加计算开销。
https 协议的工作原理
客户端在使用 HTTPS 方式与 Web 服务器通信时有以下几个步骤:
- 客户端使用 https url 访问服务器,则要求 web 服务器
建立 ssl 链接
。 - 服务器接收到客户端的请求之后,会
将网站的证书(证书中包含了公钥),传输给客户端
。 - 客户端和 服务器端开始
协商 SSL 链接的安全等级
,也就是加密等级。 - 客户端浏览器通过双方协商一致的安全等级,
建立会话密钥
,然后通过网站的公钥来加密会话密钥,并传送给网站。 - web 服务器
通过自己的私钥解密出会话密钥
。 - web 服务器
通过会话密钥加密与客户端之间的通信
。
https 协议的优缺点
- HTTPS 协议要比 HTTP 协议
安全
,可防止数据在传输过程中被窃取、改变,确保数据的完整性。 - https 握手需要解密和加密比较
费时
, - https
缓存
不如 http 高效,会增加数据开销。 - SSL 证书也需要钱,功能越强大的
证书费
用越高。 - SSL 证书需要绑定
IP
,不能再同一个 ip 上绑定多个域名,ipv4 资源支持不了这种消耗。