美文网首页前端知识点
在浏览器输入URL回车后的过程

在浏览器输入URL回车后的过程

作者: Adonia汪 | 来源:发表于2021-02-26 15:02 被阅读0次

    大致流程

    1. 解析URL
    2. DNS域名解析
    3. TCP连接(三次握手)
    4. 发送HTTP请求
    5. 服务器处理请求,返回响应结果
    6. 浏览器解析文件并渲染页面
    7. 断开TCP连接(四次挥手)

    一、URL解析

    URL解析就是当在浏览器中输入URL后,浏览器首先对拿到的URL进行识别,检验URL地址是否合法,抽取出域名字段。
    例如http://www.baidu.com,这个URL主要由三部分组成:协议名、域名、端口号。通常端口号不见是因为大部分的是使用默认端口,如HTTP默认80,HTTPS默认443。
    更详细的说,URL包含以下几个部分:
    传输协议-服务器-域名-端口-虚拟目录-文件名-参数-锚
    http-www-aspxfans.com-8080-news-index.asp-boardID=5&ID=246&page=1-name
    连接起来就是:
    http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=246&page=1#name

    二、DNS域名解析

    例如:拿www.baidu.com举例,www.baidu.com就是域名。

    www.baidu.com (域名) - DNS解析 -> 11.22.33.44 (IP地址)
    

    查询URL对应的IP地址。DNS实际上是一个域名和IP地址对应的数据库。域名和IP地址之间的转换称为域名解析。域名解析需要由专门的域名解析服务器来完成,整个过程是自动进行的。具体步骤为:
    1、先到各种缓存信息中查找


    DNS.png
    ① 浏览器缓存

    浏览器会先检查自己的DNS缓存(缓存时间比较短,TTL默认是1000且只能容纳1000条缓存),看自己的缓存中是否有www.baidu.com对应的条目,而且没有过期,如果有就返回其对应IP地址,没有则进行下一步。

    ② 操作系统缓存

    搜索操作系统的DNS缓存,如果没有找到,接着检查域名是否存在本地的Hosts(位于C:WindowSystem32driversetc)文件中,Hosts文件保存了一些以前访问过的网站的域名和IP的数据,它就像是一个本地的数据库,如果找到则返回对应的IP地址,没有则向DNS服务器发送查询请求。

    ③ 路由器缓存

    路由器查找其缓存,如果找到则返回对应IP地址,没有则下一步

    ④本地DNS缓存

    浏览器会向本地配置的首选DNS服务器ISP DNS发起域名解析请求(ISP DNS就是在客户端电脑上设置的首选DNS服务器,它们在大多数情况下都会有缓存),通过UDP协议向DNS的53端口发起请求,这个请求是递归的请求,也就是运营商的DNS服务器必须得提供给我们该域名的IP地址。如果找到则返回对应IP地址,没有则下一步。

    ⑤ LDNS向根域名服务器查询、递归查询

    递归查找的顺序是(根域名服务器,一级域名服务器,二级域名服务器,三级域名服务器)。
    在前面所有步骤没有缓存的情况下,LNDS(本地域名服务器)会向Root Name Server(根域名服务器)发起请求获得根域的IP地址,然后再像com域发起请求获得com域的IP地址,最后向www.baidu.com这个域名的DNS地址发起请求获得对应的IP地址。
    事实上,真正的网址是www.google.com.,并不是我多打了一个.,这个.对应的就是根域名服务器,默认情况下所有的网址的最后一位都是.,既然是默认情况下,为了方便用户,通常都会省略,浏览器在请求DNS的时候会自动加上,所有网址真正的解析过程为: . -> .com -> google.com. -> www.google.com.

    下面这个图很好的诠释了整个流程:

    root.png
    2、LDNS查找成功将IP地址返回给操作系统缓存起来,操作系统将IP地址返回给浏览器缓存起来,浏览器获得IP地址,发起建立连接的请求。

    三、TCP连接(三次握手)

    浏览器主机根据IP地址与服务器建立TCP连接。浏览器向服务器发送SYN连接请求,经过服务器与浏览器三次报文的交互连接建立完成。就可以发送数据了。

    TCP三次握手:

    第一次握手:客户端向服务端发送请求(SYN=1),并进入SYN_SENT状态,等待服务器确认;(你在家吗?我要来你家吃饭)
    第二次握手:服务器收到请求并确认,回复一个指令(SYN=1,ACK=1),此时服务器进入SYN_RECV状态;(在的,来吧)
    第三次握手:客户端收到服务器的回复指令并返回确认(ACK=1),客户端和服务端进入ESTABLISHED状态,完成三次握手。(好嘞)

    注:SYN(synchronous建立连接)、ACK(acknowledgement 表示响应、确认)、PSH(push表示有DATA数据传输)

    TCP.png

    四、发送HTTP请求

    握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。根据HTTP协议的要求,组织一个HTTP数据包,向服务器发送HTTP请求。
    HTTP的请求报文由请求行、请求头、空行和请求数据4部分组成。

    请求行:包括请求方法、URL、协议版本。如GET/HTTP/1.0
    请求头:包括一系列key:value成对格式的数据。比如Content-type:application/x-www-form-urlencoded。
    空行:这个也是必须的。
    请求数据:真正请求所需要的数据,比如登录时的账号和密码。

    HTTP.png

    注:HTTP请求方法详见文章---《HTTP请求方法详解》

    五、服务器处理请求,浏览器接受响应

    请求到达服务器,服务器会将收到的HTTP请求报文封装成HTTP的Request对象,并通过不同的Web服务器进行处理,处理完的结果以HTTP的Response对象返回,即HTTP响应报文,最终返回给浏览器HTML文件。
    HTTP响应报文由状态行(status line)、响应头(headers)、空行(blank line)和响应数据(response body)四部分组成。
    1、状态行由3部分组成,分别为:协议版本、状态码、状态码描述。其中协议版本与请求报文一致,状态码描述是对状态码的简单描述。

    响应的状态码
    • 1xx:指示信息-表示请求已接收,继续处理
    • 2xx:成功-表示请求已被成功接收
    • 3xx:重定向-要完成请求必须进行更进一步的操作
    • 4xx:客户端错误-请求有语法错误或请求无法实现
    • 5xx:服务器错误-服务器未能实现合法的请求
      注:平时遇到比较常见的状态码有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500。

    2、响应报头主要由Cache-Control、Server、Connection、Date等组成。
    3、响应数据为服务器返回给浏览器的信息,主要由HTML、css、js、图片等文件组成。

    六、浏览器解析文件并渲染页面

    6.1 整体流程

    1、解析html
    2、构建dom树
    3、处理CSS标记,构成层叠样式表模型CSSOM(CSS Object Model)。
    4、dom树结合cssOM,构建渲染树
    5、布局
    6、绘制
    7、JavaScript 编译执行

    6.2 过程解析

    浏览器是一个边解析边渲染的过程。首先浏览器解析HTML文件构建DOM树,然后解析CSS文件构建渲染树,等渲染树构建完成,浏览器开始布局渲染树并将其绘制到屏幕上,这个过程比较复杂,涉及到两个概念:回流(reflow)和重绘(repaint)。DOM节点的各个元素都是以盒模型存在的,这些都需要浏览器去计算其位置和大小,这个过程称为回流。当盒模型的位置、大小以及属性如颜色、字体等确定之后,浏览器便开始绘制内容,这个过程称为重绘。页面在首次加载时必然会经历回流和重绘,这是非常消耗性能的,尤其在移动设备上,它会破坏用户体验,有时会造成页面卡顿,所以应该尽可能减少回流和重绘。

    JS的解析是由浏览器中的JS解析引擎实现的。JS是单线程运行,即在同一个时间内只能做一件事,所有的任务都需要排队,前一个任务结束,后一个任务才开始。但是又存在某些任务比较耗时,所以需要一种机制可以先执行排在后面的任务,这就是:同步任务(synchronous)和异步任务(asynchronous)。JS的执行机制就可以看做是一个主线程加上一个任务队列(task queue)。同步任务就是放在主线程上执行的任务,异步任务就是放在任务队列中的任务,所有的同步任务在主线程上执行,形成一个执行栈;异步任务有了运行结果就会在任务队列中放置一个事件;脚本运行时先依次运行执行栈,然后从任务队列中提取事件,运行任务队列中的任务,这个过程是不断重复地,所有又叫事件循环。

    浏览器在解析过程中,如果遇到请求外部资源时,浏览器将重复下载该资源。请求过程是异步的,并不会影响HTML文档进行加载,但是当文档加载过程中遇到JS文件,HTML文档会挂起渲染过程,不仅要等到文档中JS文件加载完毕还要等到解析执行完毕,才会继续HTML渲染。原因是因为JS有可能修改DOM结构,这就意味着JS执行完成前,后续所有资源的下载是没有必要的,这就是JS阻塞后续资源下载的根本原因。所以js我们大都建议放在body元素之后。CSS文件的加载不影响JS文件的加载,但是却影响JS文件的执行,JS代码执行前浏览器必须保证CSS文件已经下载并执行完毕。

    注:浏览器对同一域名的并发连接数是有限的,通常为 6 个。

    宏任务
    • 同步任务:按照顺序执行,只有前一个任务完成后,才能执行后一个任务
    • 异步任务:不直接执行,只有满足触发条件时,相关的线程将该异步任务推进任务队列中,等待JS引擎主线程上的任务执行完毕之后才开始执行,例如异步ajax、DOM事件、setTimeOut等
    微任务

    微任务是ES6和Node环境下的,主要API有:Promise、process、nextTick
    微任务的执行在宏任务的同步任务之后,在异步任务之前。


    task.png

    具体执行方式详见文章-《JS事件循环机制(event loop)》


    内核.png

    七、断开TCP连接

    四次挥手:

    首先,需要明确的是,四次挥手不知道哪一方是主动方,哪一方是被动方。
    第一次挥手:主动方发送一个FIN(finish),告诉被动方:我不会再给你发数据了(当然,在FIN包之前发出去的数据,如果没有收到对应的ack确认报文,主动方依然会重新发送这些数据),但此时,主动方依然可以接收数据。(我这边没数据了,我要走啦)
    第二次挥手:被动方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1。(我知道了,我看看我这边有没有数据)
    第三次挥手:主动方进入Fin_Wait状态,等待被动方的FIN报文,被动方发送完毕后,向主动方发送FIN,告诉主动方,我的数据也发送完了,不会再给你发送数据了。(我这边也没数据了,咱可以断开连接了)
    第四次挥手:主动方收到FIN后,发送一个ACK给被动方,确认序号为收到序号+1,并关闭连接。至此完成四次挥手。(好的,拜拜)


    FIN.png
    断开连接为什么必须这么繁琐的四次挥手?

    主要是因为客户端告诉服务器想断开连接的时候,服务器的数据不一定已经处理完毕,所以服务器是先告诉客户端已经收到了它想断开连接的请求,然后当服务器中数据处理完毕后,便断开请求通知客户端,客户端收到后也断开请求并通知服务器。

    相关文章

      网友评论

        本文标题:在浏览器输入URL回车后的过程

        本文链接:https://www.haomeiwen.com/subject/rnmsfltx.html