admin 管理员组

文章数量: 887006

面试官:url输入到浏览器到页面的呈现经历了什么?
萌新:浏览器发送请求,服务器收到数据返回,浏览器拿到数据渲染页面
面试官:再详细点呢?
萌新:不造啊
ok,不多聊了,GG

这真的是一道津津乐道的面试题了,要说过程,还真没我们想的那么简单,这里给大家带来最最最详细的过程介绍

①输入url网址

②查看缓存(如果有就跳过③)

③DNS解析域名获取IP

④建立TCP连接(三次握手)

⑤浏览器向服务器发出HTTP请求拿取数据包

⑥服务器收到请求,返回数据

⑦浏览器拿到数据进行页面渲染

⑧关闭TCP连接(四次挥手)

请求详解

      • =>输入url网址
      • =>查看缓存
          • 浏览器缓存
          • >系统缓存
          • >路由缓存
          • >ISP缓存
      • =>DNS解析
          • >解析过程
            • 递归查询
            • 迭代查询
      • =>建立TCP连接
          • >第一次握手
          • >第二次握手
          • >第三次握手
      • =>HTTP请求
          • >请求行
            • 请求方法
            • 请求地址
            • 协议版本
          • >请求头
          • >请求体
      • =>浏览器接收响应
          • >状态行
            • 协议版本
            • 状态码
            • 状态码描述
          • >响应头部
          • >响应数据
      • =>页面渲染
          • >重绘(repaint或redraw)
          • >重排(重构/回流/reflow)
      • =>关闭TCP连接
          • >第一次挥手
          • >第二次挥手
          • >第三次挥手
          • >第四次挥手

=>输入url网址

有人说这也算???这不废话么,不输入网址咋开启后续,(偷笑)

=>查看缓存

缓存包括浏览器缓存=>系统缓存=>路由缓存,如果这三种都没有,就寻找ISP缓存,如果都没有就进行DNS解析

浏览器缓存

浏览器第一次向服务器发起请求时,会根据响应报文中HTTP头的缓存标识,决定是否缓存结果,是则将请求结果和缓存标识存入浏览器缓存中。浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识,同样浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中

>系统缓存

这个字面意思理解就知道了,本地打开的文件会留有一个缓存。

>路由缓存

路由缓存route cache,前端方面一般指在框架中的使用,在搭建框架项目时,有某些组件没必要多次渲染,所以需要将组件在内存中进行‘持久化’。

>ISP缓存

ISP是宽带接入提供商对大量网页进行加速的一种技术,ISP应对大量网页读取时会进行缓存,方便后续不必要的重发请求,通俗易懂点就是宽带缓存吧

=>DNS解析

DNS(Domain Name System)域名系统(服务)协议,是Internet的一项核心服务,它作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。就像拜访朋友要先知道别人家怎么走一样,Internet上当一台主机要访问另外一台主机时,必须首先获知其地址。DNS就是域名解析IP的转换服务

>解析过程

①查看本地hosts文件是否有映射,有就返回,没有下一步
②查看本地DNS解析器是否有缓存,有就返回,没有下一步
③查看本地DNS服务器是否有映射,有就返回,没有下一步

最后分两种解析:迭代和递归

递归查询

主机向本地域名服务器的查询一般都是采用递归查询。如果主机所询问的本地域名服务器不知道被查询的域名的IP地址,那么本地域名服务器就以DNS客户的身份,向其它根域名服务器继续发出查询请求报文

迭代查询

本地域名服务器向根域名服务器的查询的迭代查询。当根域名服务器收到本地域名服务器发出的迭代查询请求报文时,要么给出所要查询的IP地址,要么告诉本地服务器下一步应当向哪一个域名服务器进行查询,然后让本地服务器进行后续的查询。

查询顺序:根域服务器 ->顶级域->第二层域->子域

www.baidu.com

:顶级域
baidu:第二层域
www.baidu子域

=>建立TCP连接

获取到IP地址后,便会开始建立一次连接,这是由TCP协议完成的,主要通过三次握手进行连接。

>第一次握手

建立连接时,客户端发送SYN包(请求同步)到服务器,并进入SYN_SENT状态,等待服务器确认, 客户端:我想和你确定连接,可以吗?

>第二次握手

服务器收到SYN包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK(确认同步)包,此时服务器进入SYN_RECV状态,服务端:可以,你确定连接吗?

>第三次握手

客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,客户端:确定连接

=>HTTP请求

完整请求包括请求行,请求头和请求体

>请求行

请求行分为三个部分:请求方法、请求地址和协议版本

请求方法

HTTP定义的请求方法有8种:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS和TRACE。

最常的两种GET和POST

请求地址

URL:统一资源定位符,是一种自愿位置的抽象唯一识别方法。

http://localhost:8888/index.html

https/http:协议
localhost:主机,可换成IP,都指根域服务器
8888:端口号,默认80可以省略
index.html:路径

协议版本

协议版本的格式为:HTTP/主版本号.次版本号,常用的有HTTP/1.0和HTTP/1.1

>请求头
常见请求头格式含义
Host主机和端口号
Connection链接类型
User-Agent浏览器名称
Accept传输文件类型
Accept-Charset服务端可以发送的编码格式
Accept-Language服务端可以发送的语言
Referer页面跳转处
CookieCookie
>请求体

指POST请求发送的参数体,GET请求参数体在url地址栏中,请求体为null

=>浏览器接收响应

完整响应包括状态行,响应头部、空行以及响应数据。

>状态行

请求行分为三个部分:协议版本,状态码,状态码描述。

协议版本

同请求的协议版本

状态码

此处参考鄙人的博客有详解status状态码大全

状态码描述

对状态码的简单描述

>响应头部
常见响应头格式含义
Allow服务器支持哪些请求方法
Content-Encoding文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。
Content-Length表示内容长度
Content-Type表示后面的文档属于什么MIME类型
Date当前的GMT时间
Expires应该在什么时候认为文档已经过期,从而不再缓存它
Last-Modified文档的最后改动时间
Location客户应当到哪里去提取文档
>响应数据

返回的数据包

=>页面渲染

在浏览器还没接收到完整的 HTML 文件时,它就开始渲染页面了,首先构建DOM树和CSS样式树,然后合并为渲染树(renderingtree),接着就是布局和绘制。布局:从根节点递归调用,计算每一个元素的大小、位置等,给出每个节点所应该在屏幕上出现的精确坐标,绘制:使用GUI线程的api绘制每个节点。

在遇到外部链入的脚本标签或样式标签或图片时,会再次发送 HTTP 请求重复上述的步骤。在收到 CSS 文件后会对已经渲染的页面重新渲染,加入它们应有的样式,图片文件加载完立刻显示在相应位置。在这一过程中可能会触发页面的重绘或重排

>重绘(repaint或redraw)

当盒子的位置、大小以及其他属性,例如颜色、字体大小等都确定下来之后,浏览器便把这些原色都按照各自的特性绘制一遍,将内容呈现在页面上。重绘是指一个元素外观的改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。

>重排(重构/回流/reflow)

当渲染树中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建, 需要重新计算样式和渲染树。每个页面至少需要一次回流,就是在页面第一次加载的时候。

在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程称为重绘。

重排必定会引发重绘,但重绘不一定会引发重排。

重排的成本比重绘的成本高得多的多。DOM树里的每个结点都会有reflow方法,一个结点的reflow很有可能导致子结点,甚至父点以及同级结点的reflow。

=>关闭TCP连接

TCP建立成功后会一直存在连接状态,此时整个流程完成了,我们就需要四次挥手断开连接

>第一次挥手

服务器向浏览器发送一个FIN报文段,确认号是ack=u+1,报文的序号是v,服务器进入了CLOSE-WAIT(关闭等待)状态。这时的TCP连接处于半关闭(HALF-CLOSE)状态。即,A已经没有数据要发送了,但是B有数据发送,A还是会接收。也就是说从B到A的连接并没有关闭,这个状态可能会持续一段时间。服务器:我要关闭连接了,你还有数据吗?

>第二次挥手

浏览器收到了服务器发送的FIN报文段,进入FIN_WAIT_2状态,等待服务器发出连接释放的报文。浏览器:没有数据了,可以关闭

>第三次挥手

浏览器向服务器发送FIN报文段(FIN=1),请求关闭连接,服务器确认ack=u+1,同时服务器进入LAST_ACK状态,服务器:确认没有数据我就关了哈

>第四次挥手

服务器收到浏览器发送的FIN报文段,服务器向浏览器发送ACK报文段,确认报文段中把ACK置为1,确认号ack=w+1,而自己的序号是seq=u+1。然后浏览器进入TIME_WAIT状态,等待2MSL后浏览器收到服务器的ACK报文段以后,就关闭连接,服务器等待2MSL后没有收到回复,服务器也可以关闭连接了。浏览器:我关了你也关吧

本文标签: 浏览器 过程 页面 详细 URL