阅读 49

计算机网络之前端必备

一、计算机网络TCP

众所周知:TCP是一种可靠传输的协议。面向字节流、全双工通信、可靠、面向连接。

报文段格式

TCP虽然是面向字节流的,但是他的基本传输单元确实报文段。报文段 = 首部 + 数据部分。

首部字段中有几个字段的意义非常的重要,直接体现该段的功能。

1、实现无差错传输的解决方案

无差错传输是其最大特点,也是最难实现之处。

基本思想

  • 当我们传输出错的时候,要求重传。
  • 当我们接受方来不及接收的时候,我们可以适当减少发送的速率和发送的数量。

解决办法

  • 重传机制(自动重传请求协议ARQ)
  • 流量控制和拥塞控制

这也是我们学习TCP最为重要的东西,我们需了解TCP的可靠传输原理。

方法一: 自动重传请求协议ARQ

停止 —— 等待 ARQ

所谓停止等待协议就是每发送完一组数据后,等待对方确认并且收到确认后,再发送下一组数据。

发送数据,收到数据,发送确认,收到确认。
复制代码

无差错传输

发送方发送分组,接收方在规定时间内收到,并且回复确认.发送方再次发送.这是最为理想的情况,每次发送都在接收到上一次的确认回复后再次发送。

传输差错

传输过程中某一条发生了丢失,导致在一定时间内收不到确认回复,当超过定时器设置的时间之后,就会重新发送上一条数据。

确认丢失

上面我们说了发送时机丢失的情况,接下来我们看一下确认阶段丢失的情况:

A发送数据,B收到后发送确认消息,但是确认消息途中丢失了,A并不知道B是否收到,超过重传时间之后,就会重新发送数据,B接收到之后发现是重复发送,则丢弃该次发送的数据,重新发送确认信息。

确认迟到

A发送M1消息,B收到并发送确认。在超时时间内没有收到确认消息,A重传M1消息,B仍然收到并继续发送确认消息(B收到了2份M1)。此时A收到了B第二次发送的确认消息。接着发送其他数据。过了一会,A收到了B第一次发送的对M1的确认消息(A也收到了2份确认消息)。处理如下: A丢弃重复确认。 B丢弃重复信息。

连续ARQ协议

这是TCP的一个精华之所在,这里我们还需要知道滑动窗口协议的概念。

认识滑动窗口协议

首先我们来认识滑动窗口协议。其中包括了两个窗口,一个是发送窗口、一个是接收窗口

工作原理

发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置。接收方一般采用累积确认的方式,对按序到达的最后一个分组发送确认。也就是说接收方不必对收到的分组逐个发送确认。而是对按序到达的最后一个发送确认。发送方收到确认信息后,认为之前该信号之前的已经发送完毕,向前移动发送窗口至该信号,继续发送。

通俗来讲:发送方发送了5条消息,中间第三条丢失(3号),这时接收方只能对前两个发送确认(发送确认2)。发送方无法知道后三个分组的下落,而只好把后三个全部重传一次。

他当然也有自己的优缺点。优点是:容易实现,即时确认丢失也不必重传。但缺点是不能向发送方反映出接收方已经正确收到的所有分组信息。

一个数据报文段的状态可以分为四种:

停止等待ARQ VS 连续ARQ

通过下图分析,我们可以看出,停止等待协议的信道利用率明显过低。使用连续的ARQ协议可以大大的提高信道利用率。

方法二: 流量控制 && 拥塞控制

流量控制

当TCP连接建立之后,接收方会告诉发送方自己的接收窗口大小,从而控制发送方窗口。

如下是一个调整发送速率的例子:

拥塞控制

防止过多的数据注入网络,导致网络拥挤,路由器、链路过载等情况。

  • 与流量控制的区别:
类型 范围 面向对象 效果
流量控制 点对点,端对端 发送方 控制发送速率
拥塞控制 全局性 整个网络 防止过多的数据注入网络

具体有两种解决方案:慢开始 + 拥塞避免, 快重传 + 快恢复。

(1)慢开始 + 拥塞避免

  • 拥塞窗口

为了防止拥塞,TCP要求发送方维持一个拥塞窗口cwnd。拥塞窗口的值取决于网络拥塞程度,并且动态变化着,发送方根据拥塞窗口和接收窗口来取最小值为发送窗口的大小。

  • 慢开始

首先初始化一个慢开始门限ssthresh。

【阶段1 => 阶段2】 : 采用慢开始算法: 当开始发送数据的时候,从小到大一次递增。从最开始的cwnd = 1.每经过一次就翻一倍。因此是 1、2、4、8、16...;直到 cwnd >= ssthresh。

  • 拥塞控制

【阶段2 => 阶段3】 :采用拥塞避免算法。(加法增大) 降低增长速度,每经过一个往返时间RTT,发送方的拥塞窗口(cwnd)加1。直到遇到网络拥塞。

【阶段3 => 阶段4】:采用乘法减少。 当遇到网络拥塞的时候,立马将cwnd设置为1.将ssthresh设置为发生拥塞是拥塞窗口的一半。

【阶段4 => 阶段5】:重新执行慢开始算法。

(2)快重传 + 快恢复

首先初始化一个慢开始门限ssthresh。

【阶段1 => 阶段2】 : 采用慢开始算法: 当开始发送数据的时候,从小到大一次递增。从最开始的cwnd = 1.每经过一次就翻一倍。因此是 1、2、4、8、16...;直到 cwnd >= ssthresh。

【阶段2 => 阶段3】 :采用拥塞避免算法。(加法增大) 降低增长速度,每经过一个往返时间RTT,发送方的拥塞窗口(cwnd)加1。直到遇到网络拥塞。

【阶段3 => 阶段4】 :快重传 + 快恢复 当发生拥塞的时候,快重传算法首先要求接收方每收到一个失序的报文段后就立即发出重复确认。这样做可以让发送方及早知道有报文段没有到达接收方。发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段。立马开始重新传输。这意味这不是丢失了重传计时器,而是加快了反应。 同时将ssthresh设置为拥塞窗口的一半,cwnd也设置为一半。

【阶段4 => 阶段5】:拥塞控制 每经过一个往返时间RTT,发送方的拥塞窗口(cwnd)加1。直到遇到网络拥塞。

  • 快重传

2、TCP连接与释放

(1)建立连接的过程

建立的过程我们常称为三次握手~

SYN = 1 表示需要对方回复确认
ACK = 1 表示该条信息为确认信息
seq 表示当前的序号
ack 表示期望下次从哪开始发送


第一次:喂,你能听到我说话吗? (将初始序号发送过去)SYN = 1, seq = x
第二次:嗯,听得到,你能听到我说话吗? (回复确认)SYN = 1,ACK = 1,seq = x + 1, seq = y
第三次:嗯,我也听得到,我要开始发送数据了~(回复确认)ACK = 1, seq = x + 1, ack = y + 1

复制代码

(2)连接释放的过程

四次挥手:

SYN = 1 表示需要对方回复确认
ACK = 1 表示该条信息为确认信息
seq 表示当前的序号
ack 表示期望下次从哪开始发送
FIN 表示终止的信号,表示自己这方要准备断开连接了


第一次:喂,我要关闭连接了~ FIN = 1 seq = x
第二次:好,我还有没发送完的东西,等会 ACK = 1,seq = y,ack = x + 1
第三次:好了,我发送完毕了,我马上要断开连接了哦~ FIN = 1;ACK = 1;seq  = w,ack = x + 1;
第四次:ok,拜拜,合作愉快~~  ACK = 1;seq = x + 1, ack = w + 1
复制代码

这里的 seq,ack 是用来协商发送数据的开始序列的,当连接建立之后,发送方从那个序号开始发送,接收方就从那个序号开始接收,为了确保准确无误的接收。

二、计算机网络UDP (用户数据报协议)

UDP:面向无连接、面向报文、尽最大能力的交付,属于不可靠传输、支持一对一、一对多、多对多通信。

  • TCP vs UDP

三、计算机网络HTTP

1、计算机网络体系结构

计算机网络体系结构分为3种:OSI体系结构TCP / IP体系结构五层体系结构.

OSI是7层体系结构,
TCP/IP 是4层体系结构(网络接口层、网络层、传输层、应用层)
五层网络体系结构则把网络接口层分为了物理层和数据链路层。
复制代码

其实我们最关注的还是传输层和应用层。

2、HTTP协议的基本知识点

HTTP协议通常承载与TCP协议之上;有时候也承载与TLS和SSL之上,此时变成了HTTPS协议。

3、工作方式

  • HTTP协议采用 请求 / 响应 的工作方式
  • 具体工作流程如下:

4、HTTP报文

请求报文

响应报文

注意:

请求报文的回车换行符是必须的,请求行和状态行的空格也是必须的。
复制代码

5、HTTP请求方式

GET

从指定服务器获取数据

使用该方法后,查询字段会拼接到url末尾
请求字符串有长度限制
get方式的请求路径能被浏览器保存
get方法主要以获取数据
get方法不应该在处理铭感信息时候使用
复制代码

POST

提交指定数据给服务器处理

POST发送的请求。包含的数据字段会保存在请求体中,发送给服务器
post请求的数据没有长度大小限制
请求路径不能被保存为书签
POST请求不会保存在浏览器浏览记录中
复制代码

DELETE

按请求URL来删除指定的文件

PUT

将文件保存到url指定的位置。

HEAD

获取报文首部。同GET方式类似,但是不返回主体内容,只是返回首部信息,用来判断URI的有效性、资源更新的时间等。

OPTIONS

询问支持的方法,询问某个URI所支持的请求方式。 返回如:Allow: GET,POST,HEAD,DELETE

5、HTTP请求首部

HTTP首部是构成HTTP报文的重要内容,在客户端和服务器之间的通信过程中,无论是请求还是响应都需要请求首部,请求首部在传递的过程中起着传递额外信息的作用。(比如:主体大小、编码方式、域、认证信息等)

(1)通用首部字段

字段名 解释 书写格式
Cache-Control 控制缓冲机制,具体指令看下图,(可用于请求和响应) Cache-Control: private, max-age=0, no-cache
Date 表示HTTP报文创建时间 Date:Fri, 19 Oct 2018 09:45:13 GMT
Connection 控制代理不再转发的字段,管理持久连接。如Connection:Upgrade,那么在经过代理后,Upgrade首部字段将不会被发送至服务器。同时可以管理持久连接,Connection:Keep-Alive表示开启长连接,Connection: close表示关闭本次连接.HTTP/1.1 版本的默认连接都是持久连接。为此,客户端会在持 久连接上连续发送请求。当服务器端想明确断开连接时,则指定 Connection 首部字段的值为 Close。 Connection:Upgrade; Connection:Keep-Alive; Connection:close;
Pragma Pragma 是 HTTP/1.1 之前版本的历史遗留字段,仅作为与 HTTP/1.0 的向后兼容而定义。 Pragma: no-cache
Transfer-Encoding 规定了传输报文主体采用的编码方式 Transfer-Encoding: chunked
Via 没经过一个代理或者网关都会往该字段里面添加服务器信息,如下图

下图是上诉首部字段的图解~~

(2)请求首部字段

字段名 解释 书写格式
Accept 告诉服务器这边的用户代理能够处理的媒体类型以及优先级,使用q表示优先级,q默认是1,取值范围是0-1,1为最高 Accept: text/html,application/xhtml+xml,application/xml;q=0.
Accept-Charset 通知服务器,用户代理这边可以接受的字符集,字符集的优先顺序,q来表示优先级别 Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
Accept-Encoding 用户代理支持的压缩方式 Accept-Encoding: gzip, deflate
Accept-Language 通知服务器,用户代理支持的语言,q来表示优先级 Accept-Language: zh-cn,zh;q=0.7,en-us,en;q=0.3
Authorization 用来告知服务器,用户的代理认证信息 Authorization: Basic dWVub3NlbjpwYXNzd29yZA==
Expert 告知服务器,期望出现某种行为,比如:首先,客户端先发送了一个请求,这个请求的header中包含了一个属性expect: 100-continue。这种情况一般出现于上传大容量body或者是需要验证的时候。这时服务器会读取请求的header并返回一个100 continue的响应,如果服务器可以提供这项服务的话。客户端再将http请求发送回去。然后服务器会读取请求的body并且在成功后返回200状态码。 Expect: 100-continue
Host 告知服务器,所访问的资源在互联网中的主机名和端口(必须包含在首部内) 首部字段 Host 和以单台服务器分配多个域名的虚拟主机的工作机制 有很密切的关联,这是首部字段 Host 必须存在的意义。 Host: xxx
User-Agent 发送浏览器的类别,型号 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Ge
TE 告知服务器,客户端能够处理的响应的传输编码方式,以及相对优先级,与Accept-Encoding类似,但是该处用于传输 TE: gzip, deflate;q=0.5
Referer 指明我们当前的请求是从哪个web页面发起的 从首页发起 Referer: https://m.suning.com/
Range 告知服务器我要访问哪个范围内的资源 Range: bytes=5001-10000

下面我们再来自己分析一下请求首部中的带有if-的条件首部:

形如 If-xxx 这种样式的请求首部字段,都可称为条件请求。服务器接 收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。

  • If-Match

If-Match会传递一个ETag值过去,如果要访问的这个资源,当前的ETag正好是这个,那么就返回,如果对不上,那么就返回 412 Precondition Failed(客户端请求条件错误)。如果值是 * ,则表示只要资源存在即可。

  • If-Modified-Since

修改时间 > 传入的时间

如果在 If-Modified-Since指定的日期之后资源发生了更新,那么就返回响应,否者不会返回。

  • If-None-Modified

与 If-Match 首部字段的作用相反,只有比对传入的Etag和最新的ETag不一致才会接受请求。如果为*,则只有不存在了才会接受请求。

  • If-Unmodified-Since

修改时间 < 传入的时间

首部字段 If-Unmodified-Since 和首部字段 If-Modified-Since 的作用相 反。它的作用的是告知服务器,指定的请求资源只有在字段值内指定 的日期时间之后,未发生更新的情况下,才能处理请求。

  • If-Range

如果If-Range的值与服务器的ETag或更新时间一致,那么可以使用下方的Range字段,来返回相应范围的内容。

(3)响应首部字段

字段名 解释 书写格式
Accept-Ranges 告知客户端,我服务器可以处理范围请求 Accept-Ranges: bytes
ETag 首部字段 ETag 能告知客户端实体标识。它是一种可将资源以字符串 形式做唯一性标识的方式。服务器会为每份资源分配对应的 ETag 值。 ETag: "82e22293907ce725faf67773957acd12"
Location 以将响应接收方引导至某个与请求 URI 位置 不同的资源。 Location: http://www.usagidesign.jp/sample.html

(4)实体首部字段

字段名 解释 书写格式
Allow 资源允许请求的方式 Allow:GET, HEAD。
Expires 资源过期的日期 Expires:Fri, 20 Oct 2018 09:45:13 GMT
Last-Modified 资源最后一次修改的时间 Last-Modified:Fri, 15 Oct 2018 09:45:13 GMT
Content-Encoding, Content-Type, Content-Language, Content-Range 表示资源具体的信息

(5)Cookies相关

字段名 解释 书写格式
Set-Cookie 服务端返回,用于设置Cookie Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31
Cookie 服务器接收cookie值,由客户端发出 Cookie: status=enable

6、HTTP状态码

信息性状态码的介绍

100 Continue

100 状态码主要用于优化某些操作,比如客户端不知道服务端能否处理我们接下来要发送的这个实体主体,因此先发送一个Expert字段,并且客户端不能一直等待服务器的100Continue响应,超过一定返回客户端回自动发出该实体主体。如果服务器返回了417,说明了我们Expert字段无效,服务器无法理解。

101 Switching Protocols

Upgrade字段用于告诉服务端切换Http版本,如果可以服务端将返回101.

成功性状态码的介绍

200 ok

请求成功,同时说明响应报文中含有实体内容。

201 Created

201 Created:请求已经被实现,而且有一个新的资源已经依据请求的需要而建立,且其URI已经随Location头信息返回或者在响应体了(比如put方式上传文件)。假如需要的资源无法及时建立的话,应当返回'202Accepted'。

202 Accepted

请求已被建立,但是服务器还未对其做任何处理。

204 Not Content

服务器成功处理了请求,但是并没有返回任何实体内容。(比如刷新表单)

205 Reset Content

告知浏览器清除当前页面html表单元素。

206 Partial Content

表示成功执行了一部分后者是Range请求。比如我们使用的迅雷,我们都是片段下载,我们可以控制暂停和执行。

重定向状态码的介绍

300 Multiple Choices

多重选择,请求的资源可以包含多个位置信息,比如我们的页面可以有多个语言版本,默认会显示某个语言,用户可根据自己的情况去选择其他。

301 Moved Permanently

永久重定向。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。

302 Found

临时重定向。但资源只是临时被移动。客户端应继续使用原有URI访问。

303 See Other

查看其它地址。与301类似。其主要目的就是将POST响应定位到指定URI。后面还会说到一个307,它与301类似,我们下面做比较。

304 Not Modified

未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源,我们可以访问缓冲。

305 Use Proxy

表示我们所请求的资源需要代理才行。

307 Temporary Redirect

临时重定向。与303类似,场景:我们访问test.php,使用post请求发送数据,然后test做了处理让其重定向了一下,使用303让其重定向到test1.php。这时候我们想在test1中拿到请求数据,这时候我们发线拿不到的。但是如果我们把303改为307,那么就可以拿到数据。我们可以通过抓包工具发现,使用307之后,重定向的请求还是post,而使用303的重定向则是使用的get方式了。

客户端错误状态码的介绍

400 Bad Request

客户端请求的语法错误,服务器无法理解

401 Unauthorized

请求要求用户身份验证。

403 Forbidden

客户端的请求被拒绝了。

404 Not Found

服务器无法根据客户端的请求找到资源(网页)。平时开发中出现这个,最多的原因就是URI写错了。

405 Method Not Allowed

客户端请求中的方法被禁止,请求方式不对应。

服务器错误状态码

500 Internal Server Error

服务器内部错误。

501 Not Implemented

服务器无法正常完成请求。比如某种请求方式服务器不支持。

502 Bad Gateway

作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应

7、HTTP其他特点

四、计算机网络HTTPS

五、Web安全

六、面试题集

TCP 协议如何保证可靠传输?

为什么TCP建立连接需三次握手?

因为在网络传输中是存在延迟的,有时候可能对方没收到,也可能发生了超时重传,
所以三次握手才能最大程度上保证连接能够正确建立,不会造成死锁。

就比如一种情况:

A发送给B,但是途中延迟,超过了重传时间,这时候A发送了第二条到B,
B收到后,正式开始AB通信,AB正常通信完毕,这时候上一次发送的数据过来了,
B认为A又要连接了,就发送确认信号,但是A知道,这是上次发的,
所以就不会给B发送数据了,B自作多情的在那等啊等。A一直不发,B一直等。
这就导致了死锁发生。
复制代码

为什么TCP释放连接需四次挥手?

最后一次挥手是非常有必要的,因为只有这次确认信号收到了,
服务器才知道自己可以真正的关闭了,上一次的消息客户端是确定收到了。
复制代码

为什么客户端关闭连接前要等待2MSL时间?(TIME—WAIT)

1、为了保证服务器能接收到第四次分组数据,如果中途丢失了,
那么服务器肯定会重新发送第三次的数据,
那么客户端能够及时的再发送一次确认信号,保证服务器能准确接收到第四次握手信息

2、同时也确保我们之前发送的延迟回来的信息能够全部被处理完。
防止下一次连接时,出现上一次没处理的失效报文

复制代码

在浏览器中输入url地址到页面的呈现都发生了什么?

如果问到了这么一个过程,那么其实就是在考你HTTP事物流程。

DNS域名解析拿到IP地址
TCP三次握手建立HTTP连接
客户端发送请求到服务器
服务器处理请求并返回响应报文
浏览器解析并渲染页面,同时请求加载静态资源
TCP四次挥手断开连接
复制代码

DNS域名解析

在浏览器输入网址后,首先要经过域名解析,因为浏览器并不能直接通过域名找到对应的服务器,而是要通过 IP 地址。

认识IP地址

IP地址标识了 每一个网络和每一台主机。
复制代码

具体过程如下(如访问www.google.com)

1、首先浏览器去找自己的DNS缓冲,如果找到了直接返回,如果没找到进行下一步
2、搜索操作系统自身的DNS缓冲,如果找到了直接返回,如果没找到进行下一步
3、读取电脑hosts文件,如果该文件有配置,则直接读取返回,如果没找到进行下一步
4、向本地配置的首选DNS服务器发起域名解析请求,如果它找到了直接返回,如果没有进行下一步,哎呀我也不清楚,我去问问根域名服务器吧。
5、根域名服务器也不清楚,但是他知道com的域名服务器,于是说,你去问问com域名服务器吧
6、于是来到了com顶级域名服务器,老哥,你知道www.google.com的IP地址吗?哎呀抱歉,我也不清楚,我知道google.com服务器的地方,你去问问他吧。
7、辗转来到了google.com域名服务器这里,老哥你知道www.google.com的IP地址吗?哎呀,我还真知道,我告诉你啊,他的IP是xxxx
8、我的麻叶终于拿到了,快告诉客户端吧,我还得把这个缓冲一下,不然下次还得找个半死。
复制代码

DNS优化处理

  • DNS负载均衡:DNS负载均衡技术的实现原理是在DNS服务器中为同一个主机名配置多个IP地址,在应答DNS查询时, DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序返回不同的解析结果,将客户端的访问 引导到不同的机器上去,使得不同的客户端访问不同的服务器,从而达到负载均衡的目的。

  • CDN加速:利用DNS的重定向技术,DNS服务器会返回一个跟 用户最接近的点的IP地址给用户,CDN节点的服务器负责响应用户的请求,提供所需的内容。

浏览器解析渲染页面

我们来了解一下浏览器的渲染流程~~

  • 浏览器的组成

名称 功能
用户界面 (User Interface) 包括地址栏、后退/前进按钮、书签目录等,也就是你所看到的除了用来显示你所请求页面的主窗口之外的其他部分
浏览器引擎 (Browser Engine) 用来查询及操作渲染引擎的接口
渲染引擎 (Rendering Engine) 用来显示请求的内容,例如,如果请求内容为html,它负责解析html及css,并将解析后的结果显示出来
网络 (Networking) 用来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同平台上工作
JS解释器 (JS Interpreter) 用来解释执行JS代码
UI后端 (UI Backend) 用来绘制类似组合选择框及对话框等基本组件,具有不特定于某个平台的通用接口,底层使用操作系统的用户接口
数据存储 (DB Persistence) 属于持久层,浏览器需要在硬盘中保存类似cookie的各种数据,HTML5定义了web database技术,这是一种轻量级完整的客户端存储技术

总之浏览器由:用户界面、浏览器引擎、渲染引擎、网络、js解释器、UI后端、和数据持久层组成。下层为上层提供调用的接口和服务。

  • 浏览器是多进程的

浏览器有一个主控进程,和一些其他的进程比如:插件进程、GPU进程、tab页面(浏览器渲染进程内核)。

每种类型的插件对应一个进程,仅当使用该插件时才创建。GPU进程用于控制显卡硬件加速(3d绘制时非常需要)。每开启一个tab页面都会创建一个新的浏览器渲染进程,这使得每个tab页面互不影响,每个进程控制着当前tab页面的渲染,脚本执行和事件处理。多个空白tab会合并为一个进程。

  • 多线程的浏览器内核

每一个tab页面都可以看作是一个浏览器内核,浏览器内核是多线程的。

GUI线程:控制界面的显示
JS引擎线程:脚本的执行
网络请求线程
事件触发线程
定时器控制线程
复制代码
  • JS是单线程的

我们平时所说的js单线程是指的是js引擎线程。Js引擎执行Js时只分了一个线程给他执行,也就是我们的js引擎线程。

为什么js执行要单线程,如果多线程不是可以执行得快一点吗?

这个要回到Js历史了,布兰登·艾奇(Brendan Eich)老哥用10天创造js。当时js用来干嘛,简单的浏览器交互,验证,
操作一下dom是吧。那把它设计成那么复杂干什么,而且如果多线程的话,
操作dom会出现麻烦的事情,假设一个线程读取DOM节点数据的同时,
另一个线程把那个DOM节点删了,呵呵。所以js一个线程就够了,也就是一步一步顺序运行下来。
复制代码
  • 浏览器内核拿到内容后,渲染步骤大致可以分为以下几步:

1)HTML文档解析,构建DOM树。DOM树的构建是一个深度遍历的过程,当前节点的所有子节 点都构建完成以后,才会去构建当前节点的下一个兄弟节点。

2)将CSS解析成CSSOM树(CSS Rule Tree)。遇到css样式如link标签或者style标签时开始解析css,构建样式树。HTML解析 构建和CSS的解析是相互独立的并不会造成冲突,因此我们通常将css样式放在head中, 让浏览器尽早解析css;

3)当html的解析遇到script标签会怎样呢? 答案是停止DOM树的解析开始下载js。因为js是会阻塞html解析的,是阻塞资源。其原因在于js可能会改变html现有结构。例如有的节点是用js动态构建的,在这种情况下就会停止dom树的构建开始下载解析js。 脚本在文档的何处插入,就在何处执行。当 HTML 解析器遇到一个 script 标记时,它会暂停构建 DOM,将控制权移交给 JavaScript 引擎;等 JavaScript 引擎运行完毕,浏览器会从中断的地方恢复 DOM 构建。 而因此就会推迟页面首绘的时间。可以在首绘不需要js的情况下用async和defer实现异步加载。这样js就不会阻塞html的解析了。

4)根据DOM树和CSSOM树,来构建Render Tree(渲染树),注意渲染树,并不等于DOM树,因为一些像head或display:none的东西,就没有必要放在渲染树中了。

5)有了Render Tree,浏览器已经能知道网页中有哪些节点,各个节点的CSS定义,以及它们的从属关系,下一步操作就是Layout,顾名思义,就是计算出每个节点在屏幕中的位置。布局使用流模型的Layout算法。Layout是一个递归的过程,每个节点都负责自己及其子节点的Layout。Layout结果是相对父节点的坐标和尺寸。

6)Layout后,浏览器已经知道哪些节点要显示,每个节点的CSS属性是什么,每个节点在屏幕中的位置是哪里,就进入了最后一步painting,按照算出来的规则,通过显卡,把内容画到屏幕上。

GET和POST方式的对比?

1、应用场景不同,Get 主要用于获取资源,Post 主要用于提交数据给服务器处理。
2、Get 方式将传递的参数通过拼接URL的方式来传递,只能接收ASCII码,中文需要URL编码,长度限制。Get 方式的路径可以保存为书签,可以通过查历史记录再次调出。
3、Post 方式将参数放在了请求体中,长度不受限制,传输的数据类型不受限制,不能被保存为书签。
4、get在浏览器刷新时候是无害的,但是post请求会重新提交。
5、get方式可以被浏览器缓冲,但是post不会。
6、get方式的参数会暴露在URL的后面,所以我们不能用get方式处理一些带有铭感信息的请求


----
7、Get 和Post 本质上并没有什么不同,他们都是基于TCP连接的网络请求,只是由于HTTP的规定和客户端浏览器和服务器的规定,才有了GET和POST的不同,他们最大的不同在于语义的不同,我们使用的过程最好严格遵循语义,不要随便混用。

8、大多数框架都是尽量在一个tcp包里面把HTTP请求发出去的,但是也存在一些特殊情况:对于get请求,浏览器会发送一次TCP数据包,也就是header和data会一次性发送,而Post请求会发送两次数据包,第一次发送header,返回100Continue。第二次发送数据过去。(这一点其实并不重要,感兴趣可以了解一下)
复制代码

正在努力赶稿中~~

关注下面的标签,发现更多相似文章
评论