[TOC]

网络

网络的起源

1969年

加利福尼亚大学洛杉矶分校

斯坦福大学

加利福尼亚大学

犹他州大学

互联网——Internet(音译:因特网,英特网),网际网路

1989年

欧洲粒子物理研究所——协议(格式)

WWW(World Wide Web)

基础理论

冯诺依曼试计算机——冯诺依曼(计算机之父)

运算器:CPU,GPU

存储器:内存(断电数据清空,读写速度快)

          硬盘(辅存):数据可以持久化,读写速度相对较慢

控制器:主板上的一些器件

输入设备:键盘,鼠标,麦克风,网口

输出设备:显示器,耳机,网口

IP地址与公网

IP地址

1、IP地址的格式:

IP地址分为四个段:xxx.xxx.xxx.xxx,每个段0-255,每个段,都是由8个0|1组成的

2、IP地址的分类:

一个IP地址分为两个部分:网络ID、主机ID

网络ID和主机ID的区分,一个IP地址配合子网掩码(由连续的255和连续的0组成)即可区分网络ID和主机ID,

如:IP地址为127.127.35.26,子网掩码为255.255.0.0,则网络ID为127.127.0.0,主机ID为35.26

A类:0.0.0.0 - 127.255.255.255(一个网络能有1600+万台)

B类:128.0.0.0 - 191.255.255.255

C类:192.0.0.0 - 223.255.255.255

D类:(多播地址)

E类:

如果你想搭建一个服务器,让别人能够访问到,就必须有一个公网IP

域名与DNS解析

域名:如www.baidu.com

问:能通过域名直接访问到一台机器吗?

答:不可以的

用域名和IP形成对应关系

DNS解析

首先,计算机是不知道域名对应的IP的,问路由器,如果路由器认识这个域名,就返回一个IP,然后计算机访问这个IP。如果路由器不认识,他就问上一层路由器。如果问到了城市这个级别的路由器的时候,DNS服务器。如果DNS服务器不认识这个域名,继续向上级DNS服务器查找。

互联网建立的时候,一共13台总的DNS服务器

当像浏览器的地址栏中输入一个url按回车之后,网络中都会发生什么?

如:输入的时123.xyz

1、看浏览器的缓存

2、看本机host

C:\window\system32\drivers\etc\host

127.0.0.1即为localhost 0.0.0.0表示不知道IP,也可访问到本机

3、家里路由器

4、上级路由、城市的DNS服务器

5、继续向上级的DNS服务器找

五层网络模型

应用层 HTTP协议、DNS协议

运输层 TCP协议、UDP协议

网络层 IP地址——IP协议

数据链路层 mac地址

七层网络模型全称为Open System InterConnection Model,即开放式系统互联模型,包括应用层、会话层、表示层、传输层、网络层、数据链路层和物理层,有国际化标准组织提出,而在这个标准提出之前,TCP/IP的四层网络模型已经广泛使用,四层分别为应用层、传输层、网际层和网络接口层,但是并没有给出网络接口层的具体内容,因此在学习过程中通常将网络接口层划分为数据链路层和物理层进行学习,即应用层、传输层、网络层、数据链路层和物理层

1、应用层直接为应用进程提供服务,应用层协议定义的时应用进程间通讯和交互的规则

2、传输层负责为两台主机中的进程提供通信服务(TCP是面向连接的、可靠的/UDP提供无连接的、尽最大努力的数据传输服务)

3、网络层又是也译为网际层,它负责为两台主机提供通信服务

4、数据链路层负责将网络浇下来的IP数据报封装成帧,并在链路的两个相邻节点间传送帧

5、物理层用来确保数据可以在各种物理媒介上进行传输,为数据的传输提供可靠的环境

HTTP协议分为两个部分:请求(Request)和响应(Response)

TCP和UDP的区别

IP:把数据包送达目标主机

IP对数据的传输总共可以分为三层,即上层用户、网络层和底层(即用来传输数据的层)

整个数据传输过程可以总结为,上层用户将需要发送的数据提交给网络层,网络层需要在该数据上绑定IP头,在这个IP头中包含发送端IP、IP协议版本、接收端IP等信息,然后网络层将绑定好IP头的数据体提交给底层进行传输,当数据到达接受端后,底层将数据体提交给接收端的网络层,接收端网络层会解析该数据体,并解开IP头,将数据部分提交给接收端

这样就会产生一个问题,IP只能把数据传送给目标主机,但目标主机收到数据后无法确认该数据要传输给哪个应用程序

UDP:把数据送达应用程序

UDP全称用户数据包协议(User Datagram Protocol),是基于IP之上开发的与程序打交道的协议,UDP一个最重要的信息就是端口号,每个想访问网路上数据的程序都需要绑定一个端口号,通过端口号,UDP就能把指定的数据包发送到指定的应用程序了

在UDP中,由原先IP的三层编程了四层,加入了传输层,首先发送端将准备好的数据提交给传输层,传输层为数据包绑定UDP头信息,UDP头中包括源端口号信息、目的端口号信息等,然后传输层将绑定好UDP头的数据包提交给网络层,网络层为数据绑定IP头,然后将数据包提交到底层,底层传输到接收端后,将数据提交给接收端的网络层,传输端网络层对数据包进行解析,然后解开数据包上附带的IP头,并将数据包提交到传输端的传输层,传输层解开UDP头,识别端口信息,并把数据提交给指定的程序。

在UDP的传输过程中,有些文件会产生丢失的情况,但UDP并不会对其进行丢包重传,因此UDP会经常应用在一些注重传输速度,但不严格要求数据完整性的领域

TCP:把数据完整地送达应用程序

TCP全称传输控制协议(Transmission Control Protocol),主要用于解决UDP传输过程中产生的丢包问题和大文件分包无法还原的问题

TCP的两大特点:

  • 对于数据包丢失的情况,TCP采用丢包重传机制
  • TCP引入了数据包排序机制,用来保证把乱序的数据包合并成一个完整的文件

TCP可以分为三个阶段,分别为建立连接、传输数据和断开连接

  • 首先,建立连接阶段。这个阶段是通过“三次握手”来建立客户端和服务器之间的连接。TCP 提供面向连接的通信传输。面向连接是指在数据通信开始之前先做好两端之间的准备工作。所谓三次握手,是指在建立一个TCP连接时,客户端和服务器总共要发送三个数据包以确认连接的建立。
  • 其次,传输数据阶段。在该阶段,接收端需要对每个数据包进行确认操作,也就是接收端在接收到数据包之后,需要发送确认数据包给发送端。所以当发送端发送了一个数据包之后,在规定时间内没有接收到接收端反馈的确认消息,则判断为数据包丢失,并触发发送端的重发机制。同样,一个大的文件在传输过程中会被拆分成很多小的数据包,这些数据包到达接收端后,接收端会按照TCP头中的序号为其排序,从而保证组成完整的数据。
  • 最后,断开连接阶段。数据传输完毕之后,就要终止连接了,涉及到最后一个阶段“四次挥手”来保证双方都能断开连接

UDP的特点:

1、UDP是无连接的
2、UDP是面向报文的
3、UDP提供最大努力交付服务,但不保证交付的可靠性
4、UDP没有拥塞控制,因此网络出现拥塞时,并不会使源主机的发送速率降低
5、UDP支持一对一、一对多、多对一和多对多的交互通信
6、UDP的首部开销比较小,只有8个字节

TCP的特点:

1、TCP是面向连接的
2、TCP是可靠的交付服务
3、TCP提供全双工的通信,两顿都设有缓存,用来你临时存放通信数据
4、TCP传输面向字节流,这里的流值得是流入或流出进程的字节序列
5、每一条TCP连接唯一地被通信两顿地两个端点所确定

页面输入URL之后发生了什么

用户输入

首先用户在输入内容之后浏览器会进行判断,如果输入的为搜索内容,则会根据浏览器的默认搜索引擎将输入的字段合成带有搜索字的URL,如果用户的输入符合URL规则,则会按照规则完善URL,比如加上协议,生成标准格式的URL

URL请求过程

在准备好标准格式的URL之后,浏览器进程就会将该URL转送给网络进程,网络进程在收到URL之后就会进行真正的URL请求,首先,会查看本地是否有需要请求内容的缓存,如果有,则直接将内容返回给浏览器进程,如果没有,则首先解析URL中域名对应的IP地址,即DNS解析,如果是HTTPS协议,那还需要建立TLS连接,接下来就是利用IP地址和目标地址建立TCP连接,连接建立之后,浏览器会构建请求行、请求头和请求体,请求头中会附加域名、cookie等内容,然后将请求信息发送到服务器,服务器在接收到请求信息之后,会向浏览器返回响应头、相应行和响应体等信息,浏览器在接收到响应信息之后就要开始解析响应头的内容了

重定向

如果返回的请求头中的状态码为301或302,则浏览器会从响应头中获取重定向后的地址,然后重新发起请求,如果相应行的状态码为200,则表示浏览器可以正常处理该请求

响应数据类型处理

浏览器通过响应头中的content-type判断响应数据的数据格式类型,并将对应的数据提交到渲染进程准备进行渲染

准备渲染进程

渲染进程的准备遵循一个原则:如果请求地址与当前站点属于同一站点,即相同的协议和根域名,则使用同一个渲染进程

提交文档

渲染进程准备好之后,还需网络进程将要进行渲染的文档提交到渲染进程,接下来就是浏览器的渲染阶段了

渲染流程:HTML、CSS和JavaScript是如何变成页面的

按照渲染的时间顺序,流水线可以分为如下几个子阶段:构建DOM树、样式计算、布局阶段、分层、绘制、分块、光栅化和合成。

接下来,在介绍每个阶段的过程中,你应该重点关注以下三点内容

  • 开始每个子阶段都有其输入的内容;
  • 然后每个子阶段有其处理过程;
  • 最终每个子阶段会生成输出内容。

理解了这三部分内容,能让你更加清晰地理解每个子阶段。

构建DOM树

3、Web网络 - 图1

参考上图DOM树的生成过程,构建DOM树的输入内容是一个非常简单的HTML文件,然后经由HTML解析器解析,最终输出树状结构的DOM

样式计算

样式计算的目的是为了计算出DOM节点中每个元素的具体样式,这个阶段大体可分为三步来完成

1、把CSS转换为浏览器能够理解的结构,这里css样式的来源主要有三种,即行间样式表、外部引用css文件、内嵌css

2、转换样式表中的属性值,使其标准化,如2em、blue、bold,这些类型数值不容易被渲染引擎理解,所以需要将所有值转换为渲染引擎容易理解的、标准化的计算值,这个过程就是属性值标准化

3、计算出DOM树中每个节点的具体样式,这一步会涉及到CSS的继承规则和层叠规则,所有的子节点会继承父节点的样式,

布局阶段

其中布局阶段包括构建布局树和布局计算两部分,在构建布局树的过程中,设置display:none的元素会被布局树忽略,而布局计算即为计算dom树中元素的具体坐标位置及尺寸

3、Web网络 - 图2

分层

因为页面中有很多复杂的效果,如3D变换、页面滚动等,渲染引擎要专门为这些节点生成专门的图层,并生成一棵对应的图层树(layertree)

这里的分层规则有:

1、拥有层叠上下文属性的元素会被提升为单独的一层
2、需要剪裁(clip)的地方也会被创建为图层
如下图中的情况,盒子元素的宽高不足以显示其内部的所有文本,因此就会出现滚动条,这时候,文本部分会单独创建一个层,滚动条也会单独创建一个层

图层绘制

渲染引擎对图层的绘制会把一个图层的绘制拆分为很多小的绘制指令,然后将这些指令按照特殊顺序组成一个待绘制列表

栅格化操作

3、Web网络 - 图3

当图层绘制列表准备好之后,主线程会把绘制列表交给合成线程,通常一个页面可能很大,但是用户只能看到其中的一部分,我们把用户可以看到的这个部分叫做视口(viewport)。

在有些情况下,有的图层可以很大,比如有的页面你使用滚动条要滚动好久才能滚动到底部,但是通过视口,用户只能看到页面的很小一部分,所以在这种情况下,要绘制出所有图层内容的话,就会产生太大的开销,而且也没有必要。

合成线程会将图层划分为图块(tile),这些图块的大小通常是256x256或者512x512

然后合成线程会按照视口附近的图块来优先生成位图,实际生成位图的操作是由栅格化来执行的。通常,栅格化过程都会使用GPU来加速生成,使用GPU生成位图的过程叫快速栅格化,或者GPU栅格化,生成的位图被保存在GPU内存中。

相信你还记得,GPU操作是运行在GPU进程中,如果栅格化操作使用了GPU,那么最终生成位图的操作是在GPU中完成的,这就涉及到了跨进程操作

一旦所有图块都被光栅化,合成线程就会生成一个绘制图块的命令——“DrawQuad”,然后将该命令提交给浏览器进程。

浏览器进程里面有一个叫viz的组件,用来接收合成线程发过来的DrawQuad命令,然后根据DrawQuad命令,将其页面内容绘制到内存中,最后再将内存显示在屏幕上

整个渲染进程基本依照下图流程来完成,

3、Web网络 - 图4

重绘、重排和合成

有了上面介绍渲染流水线的基础,我们再来看看三个和渲染流水线相关的概念——“重排”“重绘”和“合成”。理解了这三个概念对于你后续Web的性能优化会有很大帮助

重排

3、Web网络 - 图5

如果你通过JavaScript或者CSS修改元素的几何位置属性,例如改变元素的宽度、高度等,那么浏览器会触发重新布局,解析之后的一系列子阶段,这个过程就叫重排。无疑,重排需要更新完整的渲染流水线,所以开销也是最大的

重绘

接下来,我们再来看看重绘,比如通过JavaScript更改某些元素的背景颜色,渲染流水线会怎样调整呢?你可以参考下图:

3、Web网络 - 图6

从图中可以看出,如果修改了元素的背景颜色,那么布局阶段将不会被执行,因为并没有引起几何位置的变换,所以就直接进入了绘制阶段,然后执行之后的一系列子阶段,这个过程就叫重绘。相较于重排操作,重绘省去了布局和分层阶段,所以执行效率会比重排操作要高一些

合成

那如果你更改一个既不要布局也不要绘制的属性,会发生什么变化呢?渲染引擎将跳过布局和绘制,只执行后续的合成操作,我们把这个过程叫做合成。具体流程参考下图

3、Web网络 - 图7

在上图中,我们使用了CSS的transform来实现动画效果,这可以避开重排和重绘阶段,直接在非主线程上执行合成动画操作。这样的效率是最高的,因为是在非主线程上合成,并没有占用主线程的资源,另外也避开了布局和绘制两个子阶段,所以相对于重绘和重排,合成能大大提升绘制效率

HTTP版本解读

HTTP/0.9

  • 因为HTTP是基于TCP协议的,所以客户端要先根据IP地址、端口号和服务器建立连接,而建立连接的过程就是TCP三次握手的过程
  • 建立好连接之后,会发送一个GET请求行的信息,比如GET index.html来请求index.html文件
  • 服务器接收请求信息之后,读取对应的HTML文件,并按照ASCII字节流的形式返回
  • HTML文件传输完成后,通过四次挥手断开连接

3、Web网络 - 图8

总的来说,当时的需求很简单,就是用来请求体积较小的html文件,因此HTTP/0.9有以下三个特点:
1、第一个就是只有一个请求行,并没有HTTP请求头和请求体,因为只需要一个请求行就可以完整表达客户端的需求了
2、第二个是服务器端也没有返回头信息,这是因为服务器也不需要告诉客户端过多的信息,只需要返回数据就可以了
3、第三个是返回的文件内容是ASCII字符流进行传输的,因为都是HTML格式文件,所以使用ASCII字节码传输是最合适的

随着万维网的告诉发展,浏览器中展示的不单单是html文件了,对多种数据展示的需求成为了HTTP/1.0的一个核心诉求

HTTP/1.0

最大特点为引入了请求头和响应头,通过键值对的方式解决了多种类型文件传输的问题,除此之外,状态码的引入使客户端可以知道请求处理的结果,HTTP/1.0中引入了Cache机制,用来缓存已经下载过的数据,可以减轻服务器的压力,服务器通过用户代理的字段来统计客户端的基础信息

那为了让客户端和服务器能更深入地交流,HTTP/1.0 引入了请求头和响应头,它们都是以为 Key-Value 形式保存的,在 HTTP 发送请求时,会带上请求头信息,服务器返回数据时,会先返回响应头信息。

3、Web网络 - 图9

要支持多种类型的文件,我们就需要解决以下几个问题

  • 首先,浏览器需要知道服务器返回的数据是什么类型的,然后浏览器才能根据不同的数据类型做针对性的处理。(需知道返回的数据类型)
  • 其次,由于万维网所支持的应用变得越来越广,所以单个文件的数据量也变得越来越大。为了减轻传输性能,服务器会对数据进行压缩后再传输,所以浏览器需要知道服务器压缩的方法。(需知道服务器的压缩方法)
  • 再次,由于万维网是支持全球范围的,所以需要提供国际化的支持,服务器需要对不同的地区提供不同的语言版本,这就需要浏览器告诉服务器它想要什么语言版本的页面。(需告诉服务器想要的语言版本)
  • 最后,由于增加了各种不同类型的文件,而每种文件的编码形式又可能不一样,为了能够准确地读取文件,浏览器需要知道文件的编码类型(需知道文件的编码类型)

HTTP/1.0在浏览器发起请求时,在请求头中加入所要请求的文件类型、期待服务器的压缩格式、编码类型以及语言类型,服务器在收到请求头时,会分析该请求头中所传入的参数,并按照要求读取所需要的数据,并按照特定编码及压缩方式进行打包,若服务器不支持特定的打包方式,则会进行替换,完成打包后,服务器会为客户端返回一个请求头,请求头中包含返回数据的类型、编码方式、压缩方式和语言类型等信息,有了响应头的信息,浏览器就会使用 br 方法来解压文件,再按照 指定的编码格式来处理原始文件,最后按照文件类型标准来解析该文件。这就是 HTTP/1.0 支持多文件的一个基本的处理流程。

HTTP/1.1

改进持久的连接

即将先前的短连接改为长连接

HTTP/1.0每次请求都要经过建立TCP连接、传输HTTP数据、断开TCP连接三个阶段,随着浏览器的普及,页面频繁发起请求会造成TCP不停地连接和断开,为解决这一问题,HTTP/1.1中引入了持久的连接,即一个TCP连接断开直接可以进行多次HTTP请求,只要浏览器和服务器没有明确表示断开连接,那么TCP会一直保持连接,持久连接在HTTP/1.1中是默认开启的,可在请求头中加入connection: close来关闭

不成熟的HTTP管化线

为解决队头阻塞的问题,HTTP/1.1中试图通过管化线的方式来解决该问题,是指客户端将整批http请求发送给服务器端,虽然可以进行整批发送请求,但是服务器端依然需要按照顺序来处理客户端的请求

提供虚拟主机的支持

在1.0中,每个域名绑定一个唯一的IP地址,因此一个服务器只能支持一个域名,但是随着虚拟主机的发展需要实现在一台物理主机上绑定多个虚拟主机,每个虚拟主机都有自己的单独的域名,这些单独的域名都公用同一个 IP 地址。

因此,HTTP/1.1 的请求头中增加了Host 字段,用来表示当前的域名地址,这样服务器就可以根据不同的 Host 值做不同的处理。

对动态生成的内容提供了完美支持

在设计 HTTP/1.0 时,需要在响应头中设置完整的数据大小,如Content-Length: 901,这样浏览器就可以根据设置的数据大小来接收数据。不过随着服务器端的技术发展,很多页面的内容都是动态生成的,因此在传输数据之前并不知道最终的数据大小,这就导致了浏览器不知道何时会接收完所有的文件数据。

HTTP/1.1 通过引入Chunk transfer 机制来解决这个问题,服务器会将数据分割成若干个任意大小的数据块,每个数据块发送时会附上上个数据块的长度,最后使用一个零长度的块作为发送数据完成的标志。这样就提供了对动态内容的支持。

客户端Cookie、安全机制

HTTP/1.1 还引入了客户端 Cookie 机制和安全机制

小结

在HTTP的发展史用,起初HTTP/0.9因为需求简单,所以客户端与服务器之间的通信也相对简单(在请求时仅采用简单的请求行的方式进行请求,并且服务器端也没必要向客户端返回过多的信息)

由于万维网的快速崛起,带来了大量新的需求,其中最核心的一个就是需要支持多种类型的文件下载, 为此 HTTP/1.0 中引入了请求头和响应头。在支持多种类型文件下载的基础之上,HTTP/1.0 还提供了 Cache 机制、用户代理、状态码等一些基础信息。

但随着技术和需求的发展,人们对文件传输的速度要求越来越高,故又基于 HTTP/1.0 推出了 HTTP/1.1,增加了持久连接方法来提升连接效率,同时还尝试使用管线化技术提升效率(不过由于各种原因,管线化技术最终被各大厂商放弃了)。除此之外,HTTP/1.1 还引入了 Cookie、虚拟主机的支持、对动态内容的支持等特性。

虽然 HTTP/1.1 在 HTTP/1.0 的基础之上做了大量的优化,但是由于一些效率问题始终很难解决,所以最终还是被 HTTP/2 所取代,这就是我们下一篇文章要介绍的内容了

HTTP/2

可参考该链接(地址

虽然 HTTP/1.1 采取了很多优化资源加载速度的策略,也取得了一定的效果,但是 HTTP/1.1对带宽的利用率却并不理想,这也是 HTTP/1.1 的一个核心问题

之所以会出现这个问题,主要是以下三个原因导致的:
1、TCP的慢启动
2、同时开启了多条TCP连接,那么这些连接会竞争固定的带宽
3、HTTP/1.1队头阻塞的问题

HTTP/2的多路复用

对于HTTP/1.1造成的队头阻塞问题,HTTP/2 的解决方案可以总结为:一个域名只使用一个 TCP 长连接和消除队头阻塞问题

3、Web网络 - 图10

该图就是 HTTP/2 最核心、最重要且最具颠覆性的多路复用机制。从图中你会发现每个请求都有一个对应的 ID,如 stream1 表示 index.html 的请求,stream2 表示 foo.css 的请求。这样在浏览器端,就可以随时将请求发送给服务器了。

服务器端接收到这些请求后,会根据自己的喜好来决定优先返回哪些内容,比如服务器可能早就缓存好了 index.html 和 bar.js 的响应头信息,那么当接收到请求的时候就可以立即把 index.html 和 bar.js 的响应头信息返回给浏览器,然后再将 index.html 和 bar.js 的响应体数据返回给浏览器。之所以可以随意发送,是因为每份数据都有对应的 ID,浏览器接收到之后,会筛选出相同 ID 的内容,将其拼接为完整的 HTTP 响应数据。

HTTP/2 使用了多路复用技术,可以将请求分成一帧一帧的数据去传输,这样带来了一个额外的好处,就是当收到一个优先级高的请求时,比如接收到 JavaScript 或者 CSS 关键资源的请求,服务器可以暂停之前的请求来优先处理关键资源的请求

多路复用的实现

参考下图

3、Web网络 - 图11

从图中可以看出,HTTP/2 添加了一个二进制分帧层,那我们就结合图来分析下 HTTP/2 的请求和接收过程。

  • 首先,浏览器准备好请求数据,包括了请求行、请求头等信息,如果是 POST 方法,那么还要有请求体。
  • 这些数据经过二进制分帧层处理之后,会被转换为一个个带有请求 ID 编号的帧,通过协议栈将这些帧发送给服务器。
  • 服务器接收到所有帧之后,会将所有相同 ID 的帧合并为一条完整的请求信息。
  • 然后服务器处理该条请求,并将处理的响应行、响应头和响应体分别发送至二进制分帧层。
  • 同样,二进制分帧层会将这些响应数据转换为一个个带有请求 ID 编号的帧,经过协议栈发送给浏览器。
  • 浏览器接收到响应帧之后,会根据 ID 编号将帧的数据提交给对应的请求

从上面的流程可以看出,通过引入二进制分帧层,就实现了 HTTP 的多路复用技术

HTTP/2其他特性

1、可以设置请求的优先级
HTTP/2 提供了请求优先级,可以在发送请求时,标上该请求的优先级,这样服务器接收到请求之后,会优先处理优先级高的请求

2、服务器推送
除了设置请求的优先级外,HTTP/2 还可以直接将数据提前推送到浏览器。你可以想象这样一个场景,当用户请求一个 HTML 页面之后,服务器知道该 HTML 页面会引用几个重要的 JavaScript 文件和 CSS 文件,那么在接收到 HTML 请求之后,附带将要使用的 CSS 文件和 JavaScript 文件一并发送给浏览器,这样当浏览器解析完 HTML 文件之后,就能直接拿到需要的 CSS 文件和 JavaScript 文件,这对首次打开页面的速度起到了至关重要的作用

3、头部压缩

无论是 HTTP/1.1 还是 HTTP/2,它们都有请求头和响应头,这是浏览器和服务器的通信语言。HTTP/2 对请求头和响应头进行了压缩,你可能觉得一个 HTTP 的头文件没有多大,压不压缩可能关系不大,但你这样想一下,在浏览器发送请求的时候,基本上都是发送 HTTP 请求头,很少有请求体的发送,通常情况下页面也有 100 个左右的资源,如果将这 100 个请求头的数据压缩为原来的 20%,那么传输效率肯定能得到大幅提升

HTTP/2的缺陷

1、TCP的队头阻塞:当出现数据丢包时,会造成TCP的队头阻塞,这样的话会大大影响数据的传输效率

2、TCP建立连接的延时:我们知道HTTP/1和HTTP/2都是使用TCP协议来传输的,而如果使用HTTPS的话,还需要使用TLS协议进行安全传输,而使用TLS也需要一个握手的过程,这样就需要有两个握手延迟过程

  • 在TCP建立连接时,需要进行三次握手才能建立连接,这样就会消耗1.5个RTT(网络延迟,1RTT即客户端向服务器端发送一个数据包的时间加上服务器端向客户端发送一个数据包的时间),也就是说,需要在消耗完1.5个RTT之后才能进行数据传输
  • 进行TLS连接,TSL建立连接所花的时间大致时需要1-2个RTT,会在HTTPS进行详细介绍

3、TCP连接僵化:即想要自由地更新内核中的TCP西医时非常困难的

4、QUIC协议

HTTP/3 中的 QUIC 协议集合了以下几点功能。

  • 实现了类似 TCP 的流量控制、传输可靠性的功能。虽然 UDP 不提供可靠性的传输,但 QUIC 在 UDP 的基础之上增加了一层来保证数据可靠性传输。它提供了数据包重传、拥塞控制以及其他一些 TCP 中存在的特性。
  • 集成了 TLS 加密功能。目前 QUIC 使用的是 TLS1.3,相较于早期版本 TLS1.3 有更多的优点,其中最重要的一点是减少了握手所花费的 RTT 个数。
  • 实现了 HTTP/2 中的多路复用功能。和 TCP 不同,QUIC 实现了在同一物理连接上可以有多个独立的逻辑数据流(如下图)。实现了数据流的单独传输,就解决了 TCP 中队头阻塞的问题。

HTTP协议详解

HTTP是hypertext transfer protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEB服
务器之间交换数据的过程。客户端连上web服务器后,若想获得web服务器中的某个web资源,需遵守一定的通讯格式,HTTP协议用
于定义客户端与web服务器通迅的格式。

以下是HTTP请求/响应的步骤:

1、客户端连接到Web服务器
一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。例如https://www.baidu.com
2、发送HTTP请求
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成
3、服务器接受请求并返回HTTP响应
Web服务器解析请求,定位请求资源。服务器将资源副本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据四部分组成
4、释放TCP连接
若connection模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接,若connection模式为keepalive,则该连接会保持一段时间,在该事件内可以继续接受请求
5、客户端浏览器解析HTML内容
客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干自己的HTML文档和文档的字符集。客户端浏览器读取响应数据的HTML,根据HTML的语法对齐进行格式化,并在浏览器窗口中显示

请求:Request

请求头和数据体

GET请求头

其中第一行为:请求方式 url 协议版本

如:GET /path?a=1&b=2 HTTP1.1

Host(存储域名):www.baidu.com

Connection:keep-alive

User-Agent:

Cookie:xxxxxxx

GET请求方式的最大特点:请求的参数都在url里

POST请求头

POST /path?a=1&b=2 HTTP1.1

Host:www.baidu.com

Connection:keep-alive

User-Agent:

Cookie:xxxxxxx

除此之外,还有一些传文件的信息

响应:Response

响应头和数据体

1、响应头(大都以键值对的方式存储)

第一行:协议版本 状态码 message

如:HTTP/1.1 200 OK

GET与POST的区别

1、在什么前提都没有的情况下,即不使用任何规范,只考虑语法和理论上的HTTP协议

GET和POST几乎没有什么区别,只有名称不一样

2、如果是基于RFC规范的,

(1)理论上的(Specification):GET和POST具有相同语法的,但是有不同的语义。GET是用来获取数据的,POST是用来发送数据的,其他方面没有区别。

(2)实现上的(Implementation):各种浏览器,就是这个规范的实现者。

常见(仅仅是常见的一些)的那些不同:

1)GET请求的数据在URL是可见的,POST请求不显示在URL中

2)GET请求对长度是有限制的,POST请求的长度是无限制的

3)GET请求的数据可以收藏为书签,POST请求到的不可收藏为书签

4)GET请求后,按后退按钮、刷新按钮无影响,POST数据会被重新提交

5)GET编码类型:application/x-www-form-url,POST的编码类型:有很多种,如:encodeapplication/x-www-form-urlencoded,multipart/form-data

6)GET历史参数会被保存在浏览器里,POST不会保存在浏览器中

7)GET只允许ASCII,POST没有编码限制,允许发二进制的

8)GET与POST相比,GET的安全性较差,因为所发数据是URL的一部分

Cookie与Session

Cookie

特点:存在客户端浏览器,每次请求都会向服务器端发送加密ID,不会因页面的关闭而消失。

1、如果我们用JS的变量来存数据,那么在页面关闭后,数据就消失了。

2、保持登陆状态时怎么做到的?

按照正常的HTTP协议来说,是做不到的,因为HTTP协议,上下文无关协议

3、所以说前端页面上,有可以持久化存储的东西。一旦登录成功,我就记载在这个(Cookie)里面,Cookie是有限制的,Cookie是存在浏览器里的,不是存在某个页面上的,是可以长期存储的。Cookie即便是保存在浏览器里,也是放在不同的域名下的。

例:登录过程

1)初始状态:没有登陆

2)访问百度的登录,输入用户名,密码

3)如果用户名和密码是正确的,百度的后端会向这个域名下,设置一个Cookie,写入用户的基本信息(加密的)。

4)以后每一次向百度发送请求,浏览器都会自动带上这些Cookie

5)服务端(后端)看到了带有ID的Cookie,就可以解析这个加密的ID,来获取到这个用户本身的ID

6)如果能获取到本身的ID,那么就证明这个用户已经登录过了。所以后端可以继续保留用户的信息。

缺点:如果某个坏人,复制了我浏览器里的Cookie,他就可以在他的电脑上登录我的账号了。

Session

特点:存在服务器端

登录信息存在服务器端,数据存在Session上也有缺点,如果用户量非常大,上亿的用户。在用户量很大的时候,服务器端会消耗大量资源

因为后端可能不止一台服务器,用户的登录信息,一般只存在一台服务器上,因为用户的登陆操作,在哪台机器上执行的,就一般存在哪台机器上。

需要通过反向代理。(轮询,IP哈希)

页面的正确打开方式

一个页面从输入 URL 到页面加载完的过程中都发生了什么事情?
加载过程:
• 浏览器根据 DNS 服务器解析得到域名的 IP 地址
• 向这个 IP 的机器发送 HTTP 请求
• 服务器收到、处理并返回 HTTP 请求
• 浏览器得到返回内容
渲染过程:
• 根据 HTML 结构生成 DOM 树
• 根据 CSS 生成 CSSOM
• 将 DOM 和 CSSOM 整合形成 RenderTree
• 根据 RenderTree 开始渲染和展示
• 遇到