输入url后,总的来说经历了如下几个过程

  • 1、DNS解析(将域名解析成IP地址)
  • 2、TCP连接(TCP三次握手)
  • 3、发送HTTP请求
  • 4、服务器处理HTTP请求,并返回请求报文
  • 5、浏览器渲染解析界面
  • 6、断开TCP连接(TCP四次挥手)

# 1、DNS解析

 浏览器通过向DNS服务器发送域名,DNS服务器查询到与域名相应的IP地址,然后返回给浏览器。浏览器再将ip地址打在协议上,同时请求参数也会在协议上搭载,然后一并发送给对应的服务器。

DNS的详细解析过程

  • 1、浏览器缓存:浏览器会按照一定的频率缓存DNS记录,所以一开始浏览器会搜索自身的DNS缓存。
  • 2、操作系统缓存:如果浏览器中找不到需要的DNS记录,那就去操作系统中找。
  • 3、本地hosts文件:如果操作系统中的缓存也没有找到或失效,浏览器就就会去读取本地的hosts文件。
  • 4、ISP的DNS服务器:ISP是互联网服务供应商(`Internet Service Provider)的简称,ISP有专门的DNS服务器应对DNS查询请求。
  • 5、根服务器:ISP的DNS服务器还找不到的话,它就会向根服务器发出请求,进行递归查询(如www.baidu.com。DNS服务器先根据域名服务器.com域名服务器的IP地址,然后再问.baidu域名服务器,依次类推)根=>顶级=>权威服务器

# 2、TCP连接

 客户端和服务端建立TCP连接需要三次握手。过程如下:

  • 1、客户端发送一个带SYN=1,Seq=X的数据包到服务端。(第一次握手由浏览器发起,告诉服务器自己要发送请求了)
  • 2、服务器接收到数据包后,发送一个SYN=1,ACK=X+1,Seq=Y的数据包到浏览器(第二次握手,由服务器发起,告诉浏览器自己准备接受数据了)
  • 3、客户端再回传一个带ACK=Y+1,Seq=Z的数据包,代表握手结束。(第三次握手,由浏览器发送,告诉服务器,自己要发送数据了)

三次握手的目的:为了防止已经失效的连接请求报文段突然又传送到了服务器端,从而产生错误。

# 3、发送HTTP请求

  请求报文由请求行、请求头和请求体三部分组成。

  • 1、请求行包含请求方法、url和协议版本。
  • 2、请求头包含请求的附加信息,由键值对组成。如Host:github.com、User-Agent:""、Connection:keep-alive以及Cookie。
  • 3、请求体主要是请求参数(Query String Parameters)。

注意:在发送HTTP请求的过程中,要先考虑浏览器缓存情况。缓存又分为强制缓存和协商缓存

  • 强制缓存: 当本地缓存中含有请求的数据且(缓存时间还未过期)时,客户端直接从本地缓存中获取数据。当本地缓存中没有请求的数据时,客户端才会从服务器获取数据。对于强制缓存,服务器响应的headrest中会用两个字段来表明——expires和cache-control

1、expires

expires的值作为服务器返回的数据到期时间。当再次请求的请求时间小于返回的此时间,则直接使用缓存数据。不足: 由于服务端时间和客户端时间可能有误差,会导致缓存命中的误差;另一方面,expires是HTTP1.0的产物,现在大多数使用cache-control来替代。

2、cache-control

cache-control 有许多属性,不同的属性代表不同的意义。

    private:客户端可以缓存。
    public:客户端和代理服务器可以缓存。
    max-age=t:缓存内容将在t秒后失效。
    no-cache:需要使用协商缓存来验证缓存数据。
    no-store:所有内容都不会缓存。
    must-revalidate:缓存内容在考虑使用一个陈旧的资源时,必须先验证它的状态,已过期的缓存将不被使用。
1
2
3
4
5
6
  • 协商缓存: 又称对比缓存,客户端会先从本地缓存中获取到一个缓存数据的标识(ETag),然后服务器检查该ETag是否失效,如果没有失效,服务器会返回304,此时客户端直接从缓存中获取数据。协商缓存又分为两种情况。   

    情况1:根据Last-modified进行协商缓存。

    Last-Modified: 服务器在响应请求时,会告诉浏览器资源的最后修改时间
    if-Modified-Since: 浏览器再次请求服务器的时候,请求头会包含此字段,后面跟着在缓存中获取的最后修改时间,服务器收到此请求头发现有if-Modified-Since,则与被请求资源的最后修改时间进行对比,如果一致则返回304和响应报文头,浏览器只需要从缓存中国获取信息就可以了。从字面上的意思看,这个字段表示从某个时间点算起,看文件是否被修改了。,
      1、如果没有被修改,那么只需要传输响应header,服务器返回304(Not Modified)。
      2、如果被修改了。那么开始传输响应一个整体,服务器返回200(OK)。
    Last-Modified也有不足之处,如果是在服务器上,一个资源被修改了,但其实际内容并没有发生改变,会因为Last-Modified时间匹配不上而返回整个实体给客户端(即使客户端缓存里有一个一模一样的资源。为了解决这个问题,所以HTTP1.1推出了ETag)。

    情况2:根据ETag来进行协商缓存

    Etag: ETag 是URL的Entity Tag,用于标识URL对象是否改变。具体内部含义是服务器控制的,就像cookie那样。ETag由服务器生成,然后通过响应头发送给客户端。然后客户端将ETag的值保存到缓存里。客户端再次发起请求时,使用If-Match/If-None-Match,该值就是保存到缓存里的ETag值 这个条件判断请求来验证资源是否修改。具体验证过程如下。
    如果是第一次请求
      1、客户端发起HTTP GET请求一个文件。
      2、服务器处理请求,返回文件内容(响应体)和一对Header。Header中包括ETag(例如2e681a-6-5d0448402")(假设服务器支持ETag生成和已经开启了ETag),状态码200(OK)。
    如果不是第一次请求
      客户端发起 HTTP GET 请求一个文件,注意这个时候客户端同时发送一个If-None-Match头,这个头的内容就是第一次请求时服务器返回的Etag:2e681a-6-5d0448402。
      服务器检查该ETag,并判断出该页面自上次客户端请求之后是否被修改,因此If-None-MatchFalse,即没有被修改,则响应header和空的body,浏览器直接从缓存中获取数据信息。返回状态码304。如果ETag被修改了,说明资源被改动过,则响应整个资源内容,返回状态码200。

# 4、服务器处理HTTP请求,并返回请求报文

响应报文由响应行、响应头部以及响应体三个部分组成。

# 5、浏览器渲染解析界面

整个渲染过程可以用如下一张图片来展示。 暂无图片

具体渲染过程如下:

  • 1、HTML解析,处理HTML标记并构建DOM树。解析过程分为两个阶段——标记化阶段和树构建阶段。标记化阶段属于词法分析阶段,将输入内容解析成多个标记。包括开始标记、结束标记、属性名和属性值。树构建阶段属于语法分析阶段,标记识别器识别标记,并传递给树构造器,最终生成vnode)。
  • 2、CSS解析,处理CSS标记并构建CSSOM树(样式规则树)。将css文件解析成StyleSheet对象,该对象包含着css规则,css规则对象包含着选择器及声明对象。
  • 3、将DOM树和CSSOM树合并成render tree(渲染树)。将每条css规则按照【从右至左】的方式在dom树上进行逆向匹配,然后生成具有样式规则描述的渲染树。
//逆向匹配的原因:
1、正向匹配,例如[div div p em],我们首先要检查当前元素到html的整条路径,找到最上层的div,再往下找,如果遇到不匹配就必须回到最上层那个div,再往下去匹配选择器中的第一个div,会所若干次才能确定匹配与否,效率很低。
2、逆向匹配时,会不断的向上找父节点进行验证。因为匹配的情况远远低于不匹配的情况,所以逆向匹配带来的优势是巨大的。浏览器从右到左进行查找的好处是为了尽早过滤掉一些无关的样式规则和元素
1
2
3
div > div.Aaron p span.red
1

而如果按从左到右的方式进行查找:

1. 先找到所有div节点
2. 第一个div节点内找到所有的子div,并且是class=”Aaron”
3. 然后再一次匹配p span.red等情况
4. 遇到不匹配的情况,就必须回溯到一开始搜索的div或者p节点,然后去搜索下个节点,重复这样的过程。这样的搜索过程对于一个只是匹配很少节点的选择器来说,效率是极低的,因为我们花费了大量的时间在回溯匹配不符合规则的节点。
1
2
3
4

从右到左来解析选择器:

  • 则首先就查找到<span class='red'>的元素。
  • firefox称这种查找方式为key selector(关键字查询),所谓的关键字就是样式规则中最后(最右边)的规则,上面的key就是span.red
  • 紧接着我们判断这些节点中的前兄弟节点是否符合p这个规则,这样就又减少了集合的元素,只有符合当前的子规则才会匹配再上一条子规则。一直找到符合条件的最上层div元素为止。
  • 4、渲染树布局,计算每个节点的集合信息。包括repaint和reflow。reflow在节点的几何大小变化时发生,会从该节点向下递归,依次计算所有元素的几何大小和位置。而repaint是在节点的几何大小没有变,只是背景等其他样式变了,或者样式visibility改为hidden时发生。
  • 5、渲染树绘制,将每个节点绘制到屏幕上。

# 6、断开TCP连接(TCP四次挥手)

断开一个tcp连接时,需要4次挥手。

  • 1、第一次挥手。主动关闭方发送一个FIN包,用来关闭主动方到被动关闭方的数据传输。就是主动关闭方告诉被动关闭方不会再发送数据了(当然在FIN包之前发送出去的数据,如果没有收到 ACK确认报文,主动关闭方依然会重新发送这些数据),但是此时主动关闭方还是可以接受数据。(主动关闭方将不会发送数据)
  • 2、第二次挥手。被动关闭方收到FIN包后,发送一个ACK包给对方。(被动关闭方知道将不会收到数据)。
  • 3、第三次挥手:被动关闭方发送一个FIN包,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了。(被动关闭方将不会发送数据)
  • 4、第四次挥手:主动关闭方收到FIN包后,发送一个ACK给被动关闭方,完成第四次挥手。(主动关闭方知道将不会收到数据) 三次握手的原因? 既要保证数据可靠传输,医药保证传输的效率。

    评 论:

Last Updated: 6/11/2024, 11:35:27 AM