✏️ Http
2022年6月20日
- 计算机网络
✏️ Http
1. 是什么
1) http 定义
- Http [HyperText Transfer Protocol] 超文本传输协议
- 超文本: 支持文字、图片、音视频、超链接等的混合体
- 传输: 进行两点之间的双向数据传输
- 协议: 是计算机世界里的一种协议和规范
2) URI & URL
① URI
- 统一资源标识符
- 一种概念,怎么实现无所谓,只要能够标识这个资源
- 例如,要找某个人
② URL
- 统一资源定位符
- 为 URI 的一种具体实现,不仅能够标识该资源,还明确了如何访问该资源
- 例如:到 xx 省 xx 市 xx 区 xx 镇 xx 号找叫 xxx 名字的人
- 格式:
- 协议: http | ftp | ...
- 主机名: ip :port
- 路径: 访问路径,默认为 index.html
- 可选参数
2. 报文格式
1) http 请求报文
① 请求行
1. 请求方法
请求方法 | 描述 |
---|---|
GET | 从服务器请求指定资源,请求报文中没有 body |
POST | 将数据放在 body 中向服务器提交数据 |
PUT | 向 URL 指定位置上传资源,会自动覆盖旧资源 |
DELETE | 请求服务器删除 URL 指定资源 |
GET VS POST
GET | POST | |
---|---|---|
定义 | 安全 & 幂等 & 可缓存 | 不安全 & 非幂等 & 不会缓存数据 |
请求数据存放位置 | URL | body |
参数格式 | ASCII 字符 | 无限制 |
参数长度限制 | 受浏览器限制, http 协议本身对 URL 长度并无规定 | 无限制 |
特别点 | GET 中也可以借助 body 传数据,但不保证一定能被接收到,需要根据浏览器的实现方式 | POST 的 URL 也可以传参数 |
包数 | 一般一个 TCP 包 | 大多 2 个 TCP 包,先发 header 包,服务器响应 100 continue,然后再发数据包,服务器响应 200,但火狐浏览器只发一个包 |
是否明文 | √ | √ |
本质 | TCP 连接 | TCP 连接,由于 http 规定、浏览器、服务器的限制,才表现不同 |
2. 空格 [sp]
3. URL
- 访问的目标地址
4. 空格 [sp]
5. 版本
- http 1.1
- http 2.0
- http 3.0
6. 回车符 [cr] + 换行符 [If]
② 请求头
- 用来告知服务器该请求和客户端本身的一些额外信息
- 为 K-V 键值对的格式,K-V 之前用
:
隔开,每个 K-V 对单独成行,以回车符 & 换行符结尾
请求头 | 作用 |
---|---|
Host | 请求的网站域名 |
Accpet | 客户端可接受的数据格式 |
Accept-Encoding | 客户端可接受的数据压缩格式 |
Accpet-Language | 客户端可接受的语言 |
Accpet-Charset | 客户端可接受的字符集 |
Cache-Control | 本次请求与响应链的缓存机制 |
Cookie | cookie |
Content-Type | 提交的数据类型 |
Content-Length | 提交的数据大小,单位:Byte |
Content-Encoding | 提交的数据压缩方式 |
Connection | 默认为 keep-alive |
User-Agent | --- |
http 缓存
强制缓存
- 缓存数据保存在浏览器的本地缓存,由浏览器判断该请求是否在过期时间内
- Status Code 后面除了显示状态码,还括号显示
from disk cache
- 借助以下 2 个响应头实现:
Cache-Control
相对时间,优先级高于Expires
Expires
绝对时间
- 借助
Cache-Control
实现流程:- 浏览器第一次访问该服务器资源时,服务器响应头会加上
Cache-Control
,里面设置了过期时间 - 浏览器再次访问该资源时,会检验该资源的缓存是否过期
- 若未过期,直接使用缓存
- 若已过期,重新请求该资源
- 浏览器再次收到请求后,会再次更新响应头的
Cache-Control
- 浏览器第一次访问该服务器资源时,服务器响应头会加上
协商缓存
- 需要借助
Cache-Control
,只有强制缓存未被命中时,才走协商缓存 - 状态码为 304,由服务器端告知客户端该资源未发生改变,如果浏览器有本地缓存,可以直接使用
- 借助 方式 1 实现:
Last-Modified
响应头 - 标识该资源最后修改时间If-Modified-Since
- 请求头
- 该资源过期后,发现响应头含有
Last-Modified
声明, - 再次发送请求的时候会带上
If-Modified-Since
, - 服务器收到请求后发现有
If-Modified-Since
,则与被请求资源的最后修改时间对比 - 若已被修改,返回最新数据
- 若未被修改,返回 304 走缓存
- 借助 方式 2 实现:
Etag
唯一标识响应资源If-None-Match
- 请求头
- 当资源过期后,发现响应头有
Etag
声明, - 再次发送请求时,会带上
If-None-Match : Etag 的值
- 服务器收到请求后进行对比
- 若已被改变,则返回最新数据
- 若未被修改,返回 304 走缓存
- 方式 2 优先级更高
- 需要借助
③ 空行
- 只包含一个回车符和一个换行符,不包含其它任何内容。
- 这个空行用于标记请求头部已结束,它是必须要有的
2) http 响应报文
① 状态行
协议版本
- http 1.1
- http 2.0
- http 3.0
空格
状态码
- 1xx
- 提示信息,表示目前是协议正在处理的中间状态,还需要后续操作
- 常见状态码
- 101
- 协议切换,例如使用 websocket 时需要从 Http 切换为 websocket
- 101
- 2xx
- 成功,报文已经收到 & 并被正确处理
- 常见状态码
- 200
- 一切正常,非 HEAD 请求,服务器返回的响应头会有 body 数据
- 204
- 成功,响应头没有 body 数据
- 206
- 用于 http 分片下载 | 断点续传
- 响应的 body 数据并不是全部,而是一部分
- 200
- 3xx
- 重定向
- 常见状态码
- 301
- 永久重定向,请求的资源已经不存在,需要改用新的 URL 重新发送请求获取资源
- 响应头中含有 Location 字段,指明后序要跳转的 URL,浏览器会自动重定向到新的 URL
- 302
- 临时重定向,请求的资源还在,但暂时需要另一个 URL 访问
- 响应头中含有 Location 字段,指明后序要跳转的 URL,浏览器会自动重定向到新的 URL
- 304
- 资源未修改,重定向到已存在的缓冲文件
- 301
- 4xx
- 客户端错误,请求报文有误,服务器无法处理
- 常见状态码
- 400
- 客户端请求的报文有误,通用错误码
- 403
- 服务器禁止访问该资源,而非客户端的请求有误
- 404
- 请求的资源在服务器上不存在 | 找不到,无法提供给客户端
- 400
- 5xx
- 客户端请求报文正确,但服务器处理时发生错误
- 常见状态码
- 500
- 服务器发生错误,通用错误码
- 501
- 客户端请求的功能还不支持
- 502
- 服务器作为网关 | 代理时返回的错误码,表示服务器自身工作正常,但访问后端服务器时发生了错误
- 503
- 服务器正忙,暂时无法响应客户端
- 500
空格
状态描述
② 响应头
响应头 | 作用 |
---|---|
Cache-Control | 客户端是否可缓存该资源 |
Content-Type | 数据类型 |
Content-Encoding | 数据压缩格式 |
Content-Length | 数据长度 |
3. http 特性
1) http 1.0
- 短连接
- 一个请求,即为一次 TCP 连接,需要经过 3 次握手过程 & 4 次挥手
- 串行请求
- 请求存在 队头堵塞
- 不支持断点续传
- 每次都会传送全部的页面和数据
2) http 1.1
- 默认长连接
- 减少 TCP 连接的重复建立 & 断开
- 只要任意一端没有明确提出断开连接,则保持 TCP 连接状态,超过一定时间没有数据交互,服务器也会主动断开
- 使用 pipeline
- 在同一个 TCP 连接中,客户端可发起多个请求,不需要串行执行
- 但服务器必须按照请求发送顺序依次执行
- 解决请求的 队头阻塞 问题
- 存在 响应的 队头阻塞
- 非默认开启,浏览器基本没有支持该技术
- 增加缓存处理
- 新的字段
Cache-Control
- 新的字段
- 增加 Host 字段
- 用在一台机子部署了多个主机,然后多个域名解析又是同一个 IP,此时加入了 Host 头就可以判断到底是要访问哪个主机
- 支持断点续传
- 响应的时候不标明
Content-Length
,客户端就无法断开连接,直到收到服务端的 EOF ,利于传输大文件
- 响应的时候不标明
3) http 2.0
- 头部压缩
HPACK
算法- 客户端 & 服务端同时维护一张头信息表,所有字段存入表中,头部不发原本的重复字段,而是发送字段对应的索引号
- 维护 静态字典、动态字典、压缩算法
- 减少传输负载
- 二进制编码
- 头信息二进制传输,称为 头信息帧
- 数据二进制传输,称为 数据帧
- 计算机无需额外对报文数据进行二进制转换,提高传输效率
- 数据流发送
- 每个请求对应的所有数据包,称为 一个数据流
- 每个数据流都有一个 id,不同数据流的帧可以乱序发送,因此可以并发不同的数据流,接收端根据数据流 id 有序组装成 http 消息
- 客户端的数据流 id 必须为奇数,可指定数据流的优先级,服务器会优先响应该请求
- 服务端的数据流 id 必须为偶数
- 多路复用
- 一个 TCP 连接中可并发多个请求 | 回应
- 解决 http 1.1 的 队头阻塞 问题
- 但仍存在 TCP 层面的 队头阻塞 问题,某个 TCP 包丢了,会阻塞该 TCP 连接中的所有 http 请求
- 多个 Stream 请求共用同一个 TCP 滑动窗口,
- 当发生数据丢失,滑动窗口是无法往前移动的,此时就会阻塞住所有的 HTTP 请求
- 服务器推送功能
- 服务器可以主动向客户端发送数据
- 例如客户端请求 html 文件,服务器除了发送该 html 文件,还可能一并发送对应的 css 文件
4) http 3.0
- 采用 UDP 作为传输层协议
- 采用 QUIC 协议
- 保证 UDP 传输的可靠性
- 解决队头阻塞问题
- 当发生丢包时,只阻塞该数据流,不影响其他数据流的并发
QUIC
给每一个Stream
都分配了一个独立的滑动窗口,这样使得一个连接上的多个 Stream 之间没有依赖关系,都是相互独立的,各自控制的滑动窗口
- 更快的连接建立
- 省却 TCP & TLS 多次握手过程
- 一个 RTT 过程即可建立连接,QUIC 内部包含了 TLS,
- 第二次连接时数据包 & QUIC 握手信息同时发送,达到 0 RTT 效果
- 连接迁移
- 之前通过 [源 ip, 源 port,目的 ip, 目的 port] 确定一条连接,当硬件设备的网络切换时,ip 发生改变,需要重新建立连接
- QUIC 通过 连接 id 标记通信的 2 个端点,只要硬件设备没有发生改变,仍保留原来的 QUIC 信息,即可重用连接