一、HTTP
1 什么是HTTP
HTTP协议又叫做超文本传输协议,当我们在浏览器输入url之后,浏览器发送请求,服务端接收到这个请求之后响应请求,然后返回内容。
在这一过程中需要一些规范来约束客户端的请求和服务端的响应,这个规范就是HTTP协议。
HTTP是我们在开发过程中接触最频繁的,每当我们排查问题的时候第一件事就是f12看看HTTP请求。
2.HTTP的发展历程
2.1 诞生
1989年蒂姆伯纳斯李提出了一种能让远隔两地的研究者们共享知识的设想,借助多文档之间相互关联形成超文本连成可相互参阅的www。
已经提出了3项www构建技术
SGML标准通用标记语言作为页面的文本标记语言的html超文本标记语言;
作为文档传递协议的http;
指定文档所在地的url统一资源定位符;
2.2 版本
-
HTTP/0.9
只支持
GET请求不支持请求头
只支持纯文本
-
HTTP/1.0
添加了
POST、HEAD等请求方法添加了请求头
Content-Type可以支持多种数据格式,除了文本也支持图片、音视频等。 -
HTTP/1.1
持久化
管线化
增了请求方式
PUT、PATCH、OPTIONS、DELETE等。客户端请求的头信息新增了
Host字段,用来指定服务器的域名。 -
HTTP/2.0
二进制分帧
多路复用
头部压缩
服务器推送
3.cookie
http是无状态的
http是不保存状态的,也就是http对发送过的请求或响应都不做持久化处理
http1.1虽然是无状态协议,但是为了实现期望的保持状态功能于是引入了cookie技术
关于cookie可以看这篇文章
架构设计:登录设计 - Session和Cookie实现登录
4.报文分类
http协议规定,请求从客户端发出,最后服务器端响应请求并返回
- 按照请求方式分
http报文分为请求报文和响应报文
请求报文是由请求方法、请求URI、协议版本、可选的请求首部字段、内容实体
响应报文是由协议版本、状态码、状态码解释短语、可选的响应首部字段、实体主体
- 按报文内容分
http报文分为报文首部和报文主体,两者最初用空行来划分,通常不一定有报文主体。
请求报文首部:请求行、请求首部字段、通用首部字段、实体首部字段、其它
响应报文首部:状态行、响应首部字段、通用首部字段、实体首部字段、其它
请求行:包含请求的方法,请求
URI和HTTP版本
状态行:包含表明响应结果的状态码,原因短语和HTTP版本
二、HTTP/1.1
1.持久化
在HTTP/1.1之前的版本,每进行一次HTTP通信就要断开一次TCP连接。这样存在很大的缺点不仅浪费而且还会导致页面刷新很慢,就现在一个网页就有上百个请求,每个请求都要去通过三次握手,四次挥手来建立连接,很影响效率。
为了解决这个效率问题,在HTTP1.1中提出了持久化连接,既然每次都要重建TCP连接,那为何不保持TCP连接呢?只要任意一端没有明确提出断开连接,则保持TCP连接,这样HTTP请求就可以基于这个连接的TCP进行。引入了持久化即TCP连接默认不关闭,可以被多个请求复用
2.管线化
管线化pipelining,也可以叫做流水线技术,基于HTTP持久化技术,我们可以在这上面进一步的优化,以前是发送请求,接收响应,再发送请求。现在TCP通道是保持连接的,那我们就可以并行发送多个HTTP请求,而不需要一个请求结束后再等发送下一个请求。
虽然管线化技术可以并发的发送了请求提高了效率,但是服务器响应的时候是排队响应的,谁先到达响应谁,如果某个响应阻塞了,后面的响应也会被阻塞,这就是队头阻塞。
三、 HTTP/2.0
1.二进制分帧
1.1 帧
在HTTP/2.0中帧是最小的通信单位。HTTP/2.0之前的版本的请求被切分成多个帧来进行通信。
在HTTP 2.0中,它把数据报的两大部分分成了header frame和 data frame。也就是头部帧和数据体帧。
每一个帧都包含固定的几个字段:length、type、flags、stream identifier、frame playload等。
其中type表示帧的类型,总共有十种类型的帧:HEADERS frame 和 DATA frame、 PRIORITY(设置流的优先级) RST_STREAM(终止流)SETTINGS(设置此连接的参数) PUSH_PROMISE(服务器推送) PING(测量 RTT) GOAWAY(终止连接)WINDOW_UPDATE(流量控制) CONTINUATION(继续传输头部数据)
1.2 流
流是连接中的一个虚拟信道,可以承载双向消息传输。每个流有唯一整数标识符。为了防止两端流ID冲突,客户端发起的流具有奇数ID,服务器端发起的流具有偶数ID。
流标识是描述二进制frame的格式,使得每个frame能够基于http2发送,与流标识联系的是一个流,每个流是一个逻辑联系,一个独立的双向的frame存在于客户端和服务器端之间的http2连接中。一个http2连接上可包含多个并发打开的流,这个并发流的数量能够由客户端设置。
2.多路复用
通过二进制分帧的方法把请求数据分成了多个帧,然后通过流来发送,每个帧相互之间没依赖关系可以分开发送,发送到了服务器再组装成一个请求。
3.header压缩
如果是在同一个网页的请求,每个请求带的头部信息大概了会是一样的,如果每次都要发送这些请求,造成了重复发送,降低了效率。
HTTP/2.0采用了HPACK压缩算法对头部数据进行压缩,同时客户端后和服务端各自缓存一份header fields表,避免了重复发送头部数据。
4.服务端推送
服务端推送简单来说,就是从以前的客户段主动获取到现在的服务端主动推送资源给客户段。
例如网页请求a.css的时候,服务端会主动把a.js推送给客户段,这样客户段需要a.js的时候就直接从本地缓存中获取了,不需要再从服务端去获取了。
四、首部
1.请求行
1.1 包含的内容
请求行是属于发送HTTP请求的内容,请求行包含了:请求方法、URI、HTTP版本三个内容。
请求方法是标识用什么方式来发送HTTP请求;
URI是HTTP请求的地址;
HTTP版本是客户端和服务端通信使用的版本。
1.1 请求方法
请求方法即发送请求的方式,包含:GET、POST、PUT、HEAD、DELETE、OPTIONS等,每一种方法都有各自不同的场景,请求方法之间也可以相互替换,比如发送数据也可以用GET。
- GET:用来从服务器获取资源
- POST:
POST方法用来向服务器传输主体 - PUT:
PUT用来修改数据 - HEAD:和
GET一样,只是不返回报文主体部分用于确认URI的有效性及资源的更新日期 - DELETE:用于删除资源
- OPTIONS:查询请求的
URI资源支持的方法
1.2 URI
说到URI,其实我们最熟悉的还是URL,那么这两者的区别是什么?
要说这两者的区别是什么我们还需要知道另外一个东西叫做URN,在了解这三者的区别之前,先知道这三者的名称。
URI:统一资源标识符,用一个标识某一个资源。
URL:统一资源定位符,用于定位资源在那个地方。
URN:统一资源名称,给资源命名。
关于这两者有什么区别其实一句话就能说明白
URI用于唯一标识某一个资源,而URL和URN是具体是实现方式,URL是通过地址来唯一标识,而URN是名称,只不过名称有重复的,所以后来没有用起来。
2 状态行
2.1 包含的内容
状态是是属于响应HTTP请求的内容,状态行包含了:HTTP版本、状态码。
HTTP版本是客户端和服务端通信使用的版本。
状态码是服务端响应客户端请求的状态,不同的状态码表示不同的响应结果。
2.2 状态码
状态码在同一个范围表示相同的意义。
状态码在同一个范围表示相同的意义。
| 状态码 | 解释 |
|---|---|
| 100-199 | 请求正在处理 |
| 200-299 | 请求响应成功 |
| 300-399 | 需要重新请求 |
| 400-499 | 客户端错误 |
| 500-599 | 服务端错误 |
常用的状态码
| 状态码 | 状态码英文名称 | 解释 |
|---|---|---|
| 200 | OK | 最常见的,表示请求成功 |
| 201 | Created | 请求成功,并创建了新的资源 |
| 204 | No Content | 该请求没有内容响应 |
| 301 | Moved Permanently | 请求有多个响应 |
| 302 | Found | 临时性重定向 |
| 304 | Not Modified | 所请求的资源未修改 |
| 400 | Bad Request | 客户端错误的请求,一般是参数错误 |
| 401 | Unauthorized | 客户端身份没有认证 |
| 403 | Forbidden | 服务端拒绝了这个请求 |
| 404 | Not Found | 找不到资源,这个程序员最熟了 |
| 500 | Internal Server Error | 服务端错误,一般是bug了 |
| 501 | Not Implemented | 服务端不支持请求的功能 |
| 502 | Bad Gateway | 服务器在充当网关或代理时,在尝试满足请求时从它访问的入站服务器接收到无效响应 |
| 503 | Service Unavailable | 服务不可达 |
| 504 | Gateway Time-out | 充当网关或代理的服务器,未及时从远端服务器获取请求 |
2.5 通用首部
| 字段名 | 说明 |
|---|---|
| Cache-Control | 控制缓存行为 |
| Connection | 控制代理不再转发的字段;管理持久化连接 |
| Date | 创建报文的日期 |
2.3 请求首部
| 字段名 | 说明 |
|---|---|
| Accept | 客户端可以处理的媒体类型,包含text/heml,application/xml等 |
| Accept-Charset | 客户端可以接受的字符集,包含utf-8,iso等 |
| Accept-Encoding | 客户端可以接收的编码方式,包含gzip |
| Accept-Language | 客户端可以接受的语言,包含zh-ch等 |
| Authorization | 给服务器的身份认证信息 |
| Expect | 要求服务器对某请求需要做出的行为 |
| From | 客户端邮件地址 |
| Host | 提供接受请求的服务器主机号和端口号 |
| If-Match | 字段值与服务器特定资源标记值(ETag)匹配才处理请求 |
| If-None-Match | 与 If-Match 相反,不匹配才处理请求 |
| If-Modified-Since | 确认本地资源是否有效,如果有更新就处理请求,否则响应返回 304 Not Modified |
| If-Unmodified-Since | 与 If-Modified-Since 相反,未发生更新才处理请求。如果有更新,则响应返回状态码 412 Precondition Failed |
| If-Range | 对资源的某个范围请求 |
| Max-Forwards | 限制代理或网关转发次数 |
| Proxy-Authorization | 提供信息给服务器对代理进行身份认证 |
| Range | 获取部分资源 |
| Referer | 当前文档的 URL |
| TE | 告知服务器可以使用哪些扩展传输编码 |
| User-Agent | 发出请求的应用程序名称 |
2.4 响应首部
| 字段 | 说明 |
|---|---|
| Accept-Ranges | 服务器可接受的资源请求范围类型 |
| Age | 资源在代理缓存中存在的时间,单位为秒 |
| ETag | 将资源以字符串形式作唯一性标识 |
| Location | 引导客户端访问另一个 URL,通常配合 3xx 响应,提供重定向 URL |
| Proxy-Authenticate | 把代理服务器所要求的认证消息发给客户端 |
| Retry-After | 告知客户端多久(具体日期或秒数)后再发送请求,主要配合状态码 503 Service Unavailable 或 3xx Redirect 响应 |
| Server | 告知客户端当前服务器安装的应用程序信息 |
| Vary | 列出所有客户端请求首部,服务器根据这些首部选择文档或产生定制内容。 |
| WWW-Authenticate | 告知客户端请求是使用的认证模式,包含Basic和Digest |
2.6 实体首部
| 字段 | 说明 |
|---|---|
| Allow | 告知客户端对特定资源能使用的 HTTP 方法。但服务器收到不支持的方法请求时,会返回状态码 405 Method Not Allow. |
| Content-Encoding | 用于对特定媒体类型的数据进行压缩。告知客户端要用的解压方式包含:gzip, compress, deflate, identity, br |
| Content-Language | 响应内容所使用的语言 |
| Content-Length | 响应消息体长度,单位为字节 |
| Content-Location | 报文主体返回资源所对应的 URL |
| Content-Range | 数据片段在整个文件中的位置 |
| Content-Type | 资源的 MIME 类型 |
| Expires | 指定日期/时间,超过即表示已过期。如果 Cache-Control 设置了 max-age 和 s-max-age,那么 Expires 会被忽略 |
| Last-Modified | 该实体最后修改时间 |