先来简介
什么是HTTP?
HyperText Transfer Protocol
,超文本传输协议,是目前互联网上应用最广泛的一种网络协议,所有的www
文件都必须遵守该标准。而Http
又使用了可靠的数据传输协议TCP
协议,不会产生数据丢失和损坏。
什么又是TCP?
计算机和网络设备相互通信,必须满足的一种规则,我们称之为协议(protocal
)
与HTTP密切关联的TCP、IP以及DNS
IP协议,位于网络层,作用是把各种数据包发送给对方,通过IP地址和MAC地址来保证数据传达。怎么保证呢?IP地址指明了节点被分配的地址,MAC地址是网卡所属的固定地址,彼此可进行配对,IP地址可变,但MAC地址基本不变。
ARP(Address Resolution Protocol)
协议是一种解析地址的协议,可根据IP地址解析出对应的MAC地址。
TCP协议是如何做到可靠的数据传输的?
首先,TCP位于传输层,为了方便传输,将大块的数据分割成以报文为单位的数据包进行管理,即所谓的字节流服务。
三次握手策略(three-way handshaking
)。TCP协议将数据发送出去后,一定会向对方确认数据是否送达,否则会按顺序重新发送相同的数据包。
字段 | 含义 |
---|---|
URG |
紧急指针是否有效。为1,表示某一位需要被优先处理 |
ACK |
确认号是否有效,一般置为1。 |
PSH |
提示接收端应用程序立即从TCP缓冲区把数据读走。 |
RST |
对方要求重新建立连接,复位。 |
SYN |
请求建立连接,并在其序列号的字段进行序列号的初始值设定。建立连接,设置为1 |
FIN |
希望断开连接。 |
三次握手流程
四次挥手流程
在HTTP1.1中,默认连接是持久连接的(即http keep-alive),特点是只要任意一端没有明确断开连接,则保持TCP连接状态。这样就可以做到同时并行的发送多个请求,而不需要一个个的等待响应。
DNS(Domain Name System)
也位于应用层的协议,它提供域名到IP地址的解析服务。
HTTP/1.1
URL与URI
URL(Uniform Resource Locator)
,网页地址URI(Uniform Resource Identifier)
,统一资源标识符
HTTP的工作流程
- 浏览器与服务器建立TCP连接,即三次握手
- TCP连接成功,浏览器发送HTTP请求命令
- 服务接收到请求并返回HTTP响应
- 服务器关闭连接,即四次挥手
- 浏览器解析请求的资源
Connection:keep-alive
可以让TCP连接保持打开,浏览器可继续通过相同的连接发送请求。其实HTTP1.1所有的请求都是默认保持持续连接的
HTTP报文
分为请求和响应报文。由多行(CR+LF作为换行符)数据结构构成的字符串文本,大致可分为报文首部和报文主体两部分。
- 请求行:包含请求方法,请求的URI和HTTP版本
- 状态行:包含响应结果的状态码
- 首部字段:包含请求和响应的各种条件、属性的各类首部;
- 其他:包含未定义的首部如Cookie等
内容协商
请求格式
# 请求方法 URL 协议/版本
GET /u013870094/article/details/79098628 HTTP/1.1
# 用于指定被请求资源的Internet主机和端口号
Host: blog.csdn.net
# 表示是否需要持久连接。
Connection: keep-alive
# 防止页面被缓存,只有一个用法, Pragma: no-cache
Pragma: no-cache
# 这个用来指定Response-Request遵循的缓存机制
# Cache-Control:Public 可以被任何缓存所缓存,多用户间共享
# Cache-Control:Private 内容只缓存到私有缓存中,不能在用户间共享
# Cache-Control:no-cache 所有内容都不会被缓存
# Cache-Control: max-age=x:缓存时间 以秒为单位
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
# 览器的名称和版本等信
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
# 浏览器可以接受的媒体类型(MIME类型)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
# 提供了Request的上下文信息的服务器,告诉服务器我是从哪个链接过来的,
Referer: https://blog.csdn.net/u013870094/article/details/79098628
# 浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate)
Accept-Encoding: gzip, deflate, br
# 浏览器申明自己接收的语言。
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: xxxxx
响应格式
HTTP/1.1 200 OK
Date: Wed, 23 Oct 2019 02:14:16 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: openresty
Vary: Accept-Encoding
Content-Encoding: gzip
Strict-Transport-Security: max-age=86400
浏览器缓存
先简单介绍下,后续有必要仔细研究下原理。
- 第一次请求,浏览器通过HTTP的header报文头部,附带
Expires,Cache-Control,Last-Modified/Etag
向服务器请求,此时服务器记录第一次请求的Last-Modified/Etag
- 再次请求,附带头部信息
Expires,Cache-Control,If-Modified-Since/Etag
- 服务器比对两次的
Last-Modified/Etag
与If-Modified-Since/Etag
判断资源未发生变化,返回304响应
缺陷
高延迟,队头阻塞,带宽无法充分利用
队头阻塞是指当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一并被阻塞,会导致客户端迟迟收不到数据。Chrome默认在同一个域名下,允许同时建立6个TCP持久连接,在当前请求没有结束之前,其他的请求只能处于被阻塞的状态;
解决办法:
- 将资源分配在不同的域名下
-
Spriting
合并多张小图为一张大图 - 将多个体积较小的Javascript合并成一个较大的文件;但当其中一个文件改变时,会导致整个文件重新被下载。
无状态特性带来巨大的头部
- 携带过多的header信息,如user-agent,cookie,accept等;
- 请求报文有过多的重复字段,资源浪费;
明文传输的不安全性
不支持服务推送
HTTP/2
SPDY协议
HTTP/2是现行HTTP协议(HTTP/1.x)的替代,但它不是重写,HTTP方法/状态码/语义都与HTTP/1.x一样。HTTP/2基于SPDY,专注于性能,最大的一个目标是在用户和网站间只用一个连接(connection)。
二进制传输
HTTP/2 将请求和响应数据分割为更小的帧,并且它们采用二进制编码。
它把TCP协议的部分特性挪到了应用层,把原来的"Header+Body"的消息"打散"为数个小片的二进制"帧"(Frame),用"HEADERS"帧存放头数据、"DATA"帧存放实体数据。HTP/2数据分帧后"Header+Body"的报文结构就完全消失了,协议看到的只是一个个的"碎片"。
HTTP/2 中,同域名下所有通信都在单个连接上完成,该连接可以承载任意数量的双向数据流。每个数据流都以消息的形式发送,而消息又由一个或多个帧组成。多个帧之间可以乱序发送,根据帧首部的流标识可以重新组装。
Header压缩
采用HPACK
算法压缩头部,压缩率50%-90%;
同时,同一个域名下的两个请求,只会发送差异数据,减少冗余的数据传输,降低开销。
多路复用
- 同一个域名下的所有通信都在单个连接上完成;
- 单个连接可以承载任意数量的双向数据流;
- 数据流以消息的形式发送,而消息由一个或多个帧组成,可以乱序发送,因为根据帧首部的流标识可以重新组装。
这样做直观的好处是:
- 同一个页面,只需要一个TCP慢连接的过程;
- 可以并行交错的发送请求,请求之间互不影响;
服务端推送
指的是服务端可以新建“流”主动向客户端发送消息,提前推送客户端需要的静态资源,减少等待的延迟。
提高安全性
为了兼容,HTTP2也是明文的,只不过格式是二进制的,但HTTP2都是https协议的,跑在TSL上面。
缺陷
TCP+TLS建立连接的时间是主要瓶颈
没有从根本上解决头阻塞问题,一旦遇到丢包,那么TCP协议还是会重新发送数据。
Future:HTTP/3
QUIC
- 基于UDP协议改造,实现了快速的握手;
- 集成了TLS的加密功能;
- 多路复用,彻底解决了头阻塞问题;
- 实现了类似TCP的流量控制、传输可靠性的功能;
延伸出的几个问题
- 网页中的图片资源为什么放在不同的域名下?
- 浏览器与服务器建立一个TCP连接后,是否会在完成一个http请求后断开?什么条件会断开?
- 一个TCP连接可以同时发送几个HTTP请求?
- 浏览器http请求的并发性是如何体现的?并发请求的数量有限制么?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。