HTTP 协议
是超文本传输协议,是浏览器和服务器之间的通信协议。
1991 年 HTTP 正式诞生,当时的版本是 0.9
HTTP/0.9 :协议定义了客户端发起请求,服务端响应请求的通信模式
HTTP/1.0:增加的接收文件类型,请求头部Accept字段告诉服务器可以接收的文件类型,响应头部 Content-Type告诉浏览器返回的文件类型
依靠头部可以实现 缓存cookie 认证信息等功能
1.0每次通信都要经过 建立连接/传输数据/断开连接三个阶段,如果一个页面引入的较多的外部文件时候,这个建立断开的过程会增大网络开销。
HTTP/1.1:增加了创建持久连接的方法,主要实现党一个连接传输完成后并不立即关闭连接而是继续传输其他数据保持到浏览器和服务器要求断开连接为止。
http/1并发能力受限制,在以下两个方面
浏览器为减轻服务器压力限制了连接数 大概6-8个,即一个连接的请求数量,会有资源文件等待加载的情况。
http/1.1自身问题‘“队头阻塞”’,多个tcp可以通用一个连接但是一个连接同一时刻只能处理一个请求,前一请求未处理完成后面的请求只能处于阻塞状态
出于这个问题 http/2 新增了二进制分帧的机制提升传输效率
HTTP/2.0:
- http/1 使用ASCII编码 http/2改为二进制数据,客户端发送二进制帧,同一个域名,一个连接可以发送多个请求,“多路复用”
- 服务端可以推送数据给浏览器
- 压缩头部体积
协议版本 | 解决的核心问题 | 解决方式 |
---|---|---|
0.9 | HTML 文件传输 | 确立了客户端请求、服务端响应的通信流程 |
1.0 | 不同类型文件传输 | 设立头部字段 |
1.1 | 创建/断开 TCP 连接开销大 | 建立长连接进行复用 |
2 | 并发数有限 | 二进制分帧 |
3 | TCP 丢包阻塞 | 采用 UDP 协议 |
TCP 是怎样建立/断开连接的?
TCP 传输控制协议,是一种面向连接的可靠的基于字节流的传输层通信协议
HTTP基于TCP实现,建立断开连接的过程被称为'三次握手'和'四次挥手'
三次握手(three-way-handshake)
tcp建立连接之前,客户端和服务端之间会发送三次数据,已确认双方的发送和接受能力,这个过程被称为三次握手
第一次握手:刚开始客户端处于 CLOSED 的状态,服务端处于 LISTEN 状态。客户端给服务端发送一个 SYN 报文,并指明客户端的初始化序列号 ISN,此时客户端处于 SYN_SEND 状态。
第二次握手:当服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且也指定了自己的初始化序列号 ISN。同时会把客户端的 ISN + 1 作为 ACK 的值,表示自己已经收到了客户端的 SYN,此时服务器处于 SYN_REVD 的状态。
第三次握手:当客户端收到 SYN 报文之后,会发送一个 ACK 报文,当然,也同样把服务器的 ISN + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于 ESTABLISHED 状态。服务器收到 ACK 报文之后,也处于 ESTABLISHED 状态,此时,双方成功建立起了连接。
为什么需要三次握手建立连接
第一次,服务端确认客户端有发送能力;
第二次,客户端确认服务端有接收和发送能力;
第三次,服务端确认客户端有接收能力;
四次挥手
客户端和服务端端开连接时需要发送四次数据,这个过程被称为四次挥手;
第一次挥手:在挥手之前服务端与客户端都处于 ESTABLISHED 状态。客户端发送一个 FIN 报文,用来关闭客户端到服务器的数据传输,此时客户端处于 FIN_WAIT_1 状态。
第二次挥手:当服务端收到 FIN 之后,会发送 ACK 报文,并且把客户端的序列号值加 1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。
第三次挥手:如果服务端同意关闭连接,则会向客户端发送一个 FIN 报文,并且指定一个序列号,此时服务端处于 LAST_ACK 的状态。
第四次挥手:当客户端收到 ACK 之后,处于 FIN_WAIT_2 状态。待收到 FIN 报文时发送一个 ACK 报文作为应答,并且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。等待一段时间后会进入 CLOSED 状态,当服务端收到 ACK 报文之后,也会变为 CLOSED 状态,此时连接正式关闭。
为什么建立连接只通信了三次,而断开连接却用了四次?
因为当服务端收到客户端的 FIN 报文后,发送的 ACK 报文只是用来应答的,并不表示服务端也希望立即关闭连接。
当只有服务端把所有的报文都发送完了,才会发送 FIN 报文,告诉客户端可以断开连接了,因此在断开连接时需要四次挥手。
可以利用 Wireshark 抓包 TCP 四次挥手
3、 HTTP 状态码
HTTP 的状态码为三位数,被分为五类:
1xx: 表示目前是协议处理的中间状态,还需要后续操作。
2xx: 表示成功状态。
3xx: 重定向状态,资源位置发生变动,需要重新请求。
4xx: 请求报文有误。
5xx: 服务器端发生错误。
常见状态码:
200 OK 成功状态码。通常在响应体中放有数据。
301 Moved Permanently即永久重定向,对应着302 Found,即临时重定向。
304 Not Modified: 当协商缓存命中时会返回这个状态码。
403 Forbidden: 这实际上并不是请求报文出错,而是服务器禁止访问,原因有很多,比如法律禁止、信息敏感。
404 Not Found: 表示服务器没找到资源,一般就是API接口地址,服务器地址不存在。
405 Method Not Allowed: 请求方法不被服务器端允许,get/post 这些没整对。
406 Not Acceptable: 资源无法满足客户端的条件。
408 Request Timeout: 服务器等待了太长时间。
409 Conflict: 多个请求发生了冲突。
413 Request Entity Too Large: 请求体的数据过大。
414 Request-URI Too Long: 请求行里的 URI 太大。
429 Too Many Request: 客户端发送的请求过多。
431 Request Header Fields Too Large请求头的字段内容太大。
500 Internal Server Error: 服务器出错了,不知道啥错。
501 Not Implemented: 表示不支持客户端请求。
502 Bad Gateway: 客户端访问服务器出错了,啥错不知道。
503 Service Unavailable: 表示服务器繁忙。