HTTP
总结一下最近关于HTTP的理解
- HTTP/1.1
- HTTP/2
- HTTP/3
时间线
时间 | 版本 | 功能 |
---|---|---|
1991 | 0.9 | 只支持GET 请求方法获取文本数据(比如HTML文档),且不支持请求头、响应头等,无法向服务器传递太多信息 |
1996 | 1.0 | 支持POST 、HEAD 等请求方法,支持请求头、响应头等,支持更多种数据类型(不再局限于文本数据)浏览器的每次请求都需要与服务器建立-个TCP连接,请求处理完成后立即断开TCP连接 |
1997 | 1.1 | 最经典、使用最广泛的版本支持PUT 、DELETE 等请求方法采用持久连接 (Connection: keep-alive),多个请求可以共用同一个TCP连接 |
2015 | 2.0 | |
2018 | 3.0 |
标准
口由万维网协会 (W3C)、互联网工程任务组 (ETF) 协调制定,最终发布了一系列的RFC
在RFC 5234中表明:ABNF用作internet中通信协议的定义语言
ABNF是最严谨的HTTP报文格式描述形式
格式
请求方法
方法名 | 用途 |
---|---|
GET | 常用于读取的操作,请求参数直接拼接在URL的后面(浏览器对URL是有长度限制的) |
POST | 常用于添加、修改、删除的操作,请求参数可以放到请求体中(没有大小限制) |
HEAD | 请求得到与GET请求相同的响应,但没有响应体;使用场景:下载大文件前,先获取其大小,再決定是否要下载。以此可以节约带宽资源 |
OPTIONS | 用于获取目的资源所支持的通信选项,比如服务器支持的请求方法 |
PUT | 用于对已存在的资源进行整体覆盖 |
PATCH | 用于对资源进行部分修改(资源不存在,会创建新的资源) |
DELETE | 用于删除指定的资源 |
TRACE | 请求服务器回显其收到的请求信息,主要用于HTTP请求的测试或诊断 |
CONNECT | 可以开启一个客户端与所请求资源之间的双向沟通的通道,它可以用来创建隧道 (tunnel)可以用来访问采用了 SSL (HTTPS) 协议的站点 |
头部字段
请求头字段
字段 | 说明 | 示例 |
---|---|---|
User-Agent | 浏览器的身份标识字符串 | User-Agent: Mozilla/5.0 (X11;Linux x86_64; rv:12.0) Gecko/20100101 Firefox/21.0 |
Host | 服务器的域名、端口号 | Host: localhost:80 |
Date | 发送该消息的日期和时间 | Date: Tue, 15 Nov 1994 08:12:31 GMT |
Referer | 表示浏览器所访问的前一个页面正是前一个页面的某个链接将浏览器带到了当前这个页面 | Referer: https://www.baidu.com |
Content-Type | 请求体的类型 | Content-Type: multipart/form-data |
Content-Length | 请求体的长度(字节为单位) | Content-Length: 232 |
Accept | 能够接受的响应内容类型(Content-Types) | Accept: text/plain |
Accept-Charset | 能够接受的符集 | Accept-Charset: GB2312,utf-8;q=0.7,*; q=0.7 |
Accept-Encoding | 能够接受的编码方式列表 | Accept-Encoding: gzip, deflate |
Accept-Language | 能够接受的响应内容的自然语言列表 | Accept-Language: en-US |
Range | 仅请求某个实体的一部分。字节偏移以0开始 | Range: bytes=500-999 |
Origin | 发起一个针对跨域资源共享的请求 | Origin: https://www.baidu.com |
Cookie | 之前由服务器通过set-Cookie发送的cookie | Cookie: Version=1; Skin=new; |
Connection | 该浏览器根要优先伅用的连接类型 | Connection: keep-alive |
Cache-Control | 用来指定在这次的请求/响应链中的所有缓存机制都必须遵守的指令 | Cache-Control: no-cache |
q值越大,优先级越高。默认1.0
响应头字段
字段 | 说明 | 示例 |
---|---|---|
Content-Type | 响应体的类型 | Content-Type: text/html; charset=utf-8 |
Content-Encoding | 内容所使用的编码类型 | Content-Encoding: gzip |
Content-Length | 响应体的长度(字节为单位) | Content-Length: 348 |
Content-Disposition | 一个可以让客户端下载文件并建议文件名的头部 | Content-Disposition: attachment;filename=”fname.ext” |
Accept-Ranges | 服务器支持哪些种类的部分内容范围 | Accept-Ranges: bytes |
Content-Range | 这条部分消息是属于完整消息的哪部分 | Content-Range: bytes 21010-47021/47022 |
Access-Control-Allow-Origin | 指定哪些网站可参与到跨来源资源共享过程中 | Access-Control-Allow-Origin:* |
Location | 用来进行重定向,或者在创建了某个新资源时使用 | Location: http://www.w3.org |
Set-Cookie | 返回一个Cookie让客户端去保存 | Set-Cookie: UserID=JohnDoe; Max Age=3600; Version=1 |
Connection | 针对该连接所预期的选项 | Connection: close |
Cache-Control | 向从服务器直到客户端在内的所有缓存机制告知,它们是否可以缓存这个对象。单位为秒 | Cache-Control: max-age=3600 |
HTTP2
数据流:已建立的连接内的双向字节流,可以承载一条或多条消息
所有通信都在一个TCP连接上完成,此连接可以承载任意数量的双向数据流
消息:与逻辑HTTP请求或响应消息对应,由一系列帧组成
帧:HTTP/2
通信的最小单位,每个帧都包含帧头 (会标识出当前帧所属的数据流)
来自不同数据流的帧可以交错发送,然后再根据每个帧头的数据流标识符重新组装
特性
二进制格式
HTTP/2.0
采用二进制格式传输数据,而非HTTP/1.1
的文本传输
二进制格式在协议的解析和优化扩展上带来更多的优势和可能
多路复用
客户端和服务器可以将 HTTP消息分解为互不依赖的帧,然后交错发送,最后再在另一端把它们重新组装起来
- 并行交错地发送多个请求,请求之间互不影响
- 并行交错地发送多个响应,响应之间互不干扰
不必再为绕过 HTTP/1.1限制而做很多工作
比如image sprites、合并CSS\JS. 内嵌CSS\JS\Bas64图片,城名分片等
优先级
HTTP/2
标准允许每个数据流都有一个关联的权重和依赖关系
- 可以向每个数据流分配一个介于1至256之间的整数
- 每个数据流与其他数据流之问可以存在显式依赖关系
客户端可以构建和传递“优先级树”,表明它倾向于如何接收响应
服务器可以使用此信意通过控制CPU,内存和其他资源的分配设定数据流处理的优先级,在资源数据可用之后,确保将高优先级响应以最优方式传输至客户端。
头部压缩
HTTP/2
使用HPACK
压缩请求头和响应头,可以极大减少头部开销,进而提高性能。
服务器推送
服务器可以对一个客户端请求发送多个响应,除了对最初请求的响应外,服务器还可以向客户端推送额外资源,而无需客户端额外明确地请求。
问题
队头阻塞
HTTP/2
是基于TCP
协议的, 传输过程相当于队列,串行发送。如果第一个数据包丢失,为了保证有序性,后续数据要等到队头数据重传后才可继续。
握手延迟
由于HTTP/2
的连接是基于TCP,并且前身SPDY的原因又做TLS/SSL安全套接层,所以握手时间太长。
HTTP/3
特性
连接迁移
TCP基于4要素 (源1P、源端口、目标1P、目标端口),切换网络时至少会有一个要素发生变化,导致连接发生变化。当连接发生变化时,如果还使用原来的TCP连接,则会导致连接失败,就得等原来的连接超时后重新建立连接,所以我们有时候发现切换到一个新网络时,即使新网络状況良好,但内容还是需要加载很久,如果实现得好,当检测到网络变化时立刻建立新的TCP连接,即使这样,建立新的连接还是需要几百毫秒的时间。
QUIC的连接不受4要素的影响,当4要素发生变化时,原连接依然维持。QUIC连接不以4要素作为标识,而是使用一组Connection 1D(连接D)来标识一个连接。即使IP或者端口发生变化,只要Connection 1D没有变化,那么连接依然可以维持
当设备连接到Wi-Fi时,将进行中的下载从蜂窝网络连接转移到更快速的Wi-Fi连接
当Wi-Fi连接不再可用时,将连接转移到蜂窝网络连接