> 文档中心 > 【url输入了之后会发生什么?】最细解法,从输入URL到页面渲染的过程

【url输入了之后会发生什么?】最细解法,从输入URL到页面渲染的过程

【url输入了之后会发生什么?】最细解法,从输入URL到页面渲染的过程

  • 概述
  • 输入网址
  • DNS解析
  • 建立tcp连接
  • 客户端发送HTPP请求
  • 服务器处理请求
  • 服务器响应请求
  • tcp连接断开
  • 浏览器展示html
  • 参考博客

概述

url输入后响应过程:
输入网址敲回车->查 DNS->找到 IP 地址->通过 TCP 三次握手建立连接->浏览器发送 Http 请求->收到回应->浏览器渲染页面->结束连接
【url输入了之后会发生什么?】最细解法,从输入URL到页面渲染的过程
流程可以理解为下图:
在这里插入图片描述

输入网址

输入网址的时候,浏览器其实就已经在智能的匹配可能得 url 了,他会从历史记录,书签等,找到已经输入的字符串可能对应的 url,然后给出智能提示,可以补全url地址。

  • 浏览器进程检查url,组装协议,构成完整的url,这时候有两种情况:
    • 输入的是搜索内容:地址栏会使用浏览器默认的搜索引擎,来合成新的带搜索关键字的URL。
    • 输入的是请求URL:地址栏会根据规则,给这段内容加上协议,合成为完整的URL;
  • 浏览器进程通过 进程间通信(IPC) 把url请求发送给网络进程;
  • 网络进程接收到url请求后检查本地缓存是否缓存了该请求资源,如果有则将该资源返回给浏览器进程;

DNS解析

  • 准备IP地址和端口:进行DNS解析时先查找缓存,没有再使用DNS服务器解析,查找顺序为:
    浏览器缓存–>本机缓存–>hosts文件–>路由器缓存–>ISP DNS缓存–>DNS递归查询| DNS迭代查询
  • DNS递归查询
    【url输入了之后会发生什么?】最细解法,从输入URL到页面渲染的过程
  • DNS迭代查询
    在这里插入图片描述

建立tcp连接

  • 拿到域名对应的IP地址之后,浏览器会以一个随机端口(1024<端口<65535)向服务器的WEB程序(常用的有nginx等)80端口发起TCP的连接请求。这个连接请求到达服务器端后(这中间通过各种路由设备,局域网内除外),进入到网卡,然后是进入到内核的TCP/IP协议栈(用于识别该连接请求,解封包,一层一层的剥开),还有可能要经过Netfilter防火墙(属于内核的模块)的过滤,最终到达WEB程序,最终建立了TCP/IP的连接。
  • 通过三次握手建立TCP连接过程:
      【url输入了之后会发生什么?】最细解法,从输入URL到页面渲染的过程
    服务器端收到后,也进入ESTABLISHED状态,由此成功建立了TCP连接,可以开始数据传送;

客户端发送HTPP请求

建立了TCP连接之后,发起一个http请求。一个典型的 http request header 一般需要包括请求的方法,例如 GET 或者 POST 等,不常用的还有 PUTDELETE HEADOPTION以及 TRACE 方法,一般的浏览器只能发起 GET 或者 POST 请求。
客户端向服务器发起http请求的时候,会有一些请求信息,请求信息包含三个部分:

  • 方法URL议/版本
  • 请求头(Request Header)
    请求头包含许多有关的客户端环境和请求正文的有用信息。例如,请求头可以声明浏览器所用的语言,请求正文的长度等。
  • 请求正文
    请求头和请求正文之间是一个空行,这个行非常重要,它表示请求头已经结束,接下来的是请求正文。请求正文中可以包含客户提交的查询字符串信息。
    实例:
GET/sample.jspHTTP/1.1Accept:image/gif.image/jpeg,*/*Accept-Language:zh-cnConnection:Keep-AliveHost:localhostUser-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)Accept-Encoding:gzip,deflateusername=jinqiao&password=1234

服务器处理请求

后端从在固定的端口接收到TCP报文开始,它会对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用。
一些大一点的网站会将你的请求到反向代理服务器中,因为当网站访问量非常大,网站越来越慢,一台服务器已经不够用了。于是将同一个应用部署在多台服务器上,将大量用户的请求分配给多台机器处理。
此时,客户端不是直接通过HTTP协议访问某网站应用服务器,而是先请求到Nginx,Nginx再请求应用服务器,然后将结果返回给客户端,这里Nginx的作用是反向代理服务器。同时也带来了一个好处,其中一台服务器万一挂了,只要还有其他服务器正常运行,就不会影响用户使用。

服务器响应请求

这一步,它会把它的处理结果返回,也就是返回一个HTPP响应。
HTTP响应与HTTP请求相似,HTTP响应也由3个部分构成,分别是:

  • 状态行
    协议版本:是用http1.0还是其他版本
    状态代码:状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。如下:
    1xx:信息性状态码,表示服务器已接收了客户端请求,客户端可继续发送请求。
    2xx:成功状态码,表示服务器已成功接收到请求并进行处理。
    3xx:重定向状态码,表示服务器要求客户端重定向。
    4xx:客户端错误状态码,表示客户端的请求有非法内容。
    5xx:服务器错误状态码,表示服务器未能正常处理客户端的请求而出现意外错误。

    状态描述:状态描述给出了关于状态代码的简短的文字描述。比如状态代码为200时的描述为 ok

  • 响应头(Response Header)
    响应头部:由关键字/值对组成,每行一对,关键字和值用英文冒号":"分隔。

  • 响应正文:包含着我们需要的一些具体信息,比如cookie,html,image,后端返回的请求数据等等。
    响应正文和响应头之间有一行空格,表示响应头的信息到空格为止,

HTTP/1.1 200 OKDate: Sat, 31 Dec 2005 23:59:59 GMTContent-Type: text/html;charset=ISO-8859-1Content-Length: 122
  • 如果是301/302表示服务器已更换域名需要重定向,这时网络进程会从响应头的Location字段里面读取重定向的地址,然后再发起新的HTTP或者HTTPS请求,跳回dns解析。
  • 如果是200,就检查Content-Type字段,值为text/html说明是HTML文档,是application/octet-stream说明是文件下载;

tcp连接断开

请求结束,当通用首部字段Conection不是Keep-Alive时,即不为TCP长连接时,通过四次挥手断开TCP连接:
【url输入了之后会发生什么?】最细解法,从输入URL到页面渲染的过程

  • 第一次:客户端(主动断开连接)发送数据包给服务器,其中标志位FIN=1,序号位seq=u,并停止发送数据;
  • 第二次:服务器收到数据包后,由于还需传输数据,无法立即关闭连接,先返回一个标志位ACK=1,序号seq=v,确认号ack=u+1的数据包;
  • 第三次:服务器准备好断开连接后,返回一个数据包,其中标志位FIN=1,标志位ACK=1,序号seq=w,确认号ack=u+1;
  • 第四次:客户端收到数据包后,返回一个标志位ACK=1,序号seq=u+1,确认号ack=w+1的数据包。

浏览器展示html

【url输入了之后会发生什么?】最细解法,从输入URL到页面渲染的过程

  • 准备渲染进程:浏览器进程检查当前url是否与之前打开了渲染进程的页面的根域名相同,如果相同,则复用原来的进程,如果不同,则开启新的渲染进程;

  • 提交文档

    • 渲染进程准备好后,浏览器向渲染进程发起“提交文档”的消息,渲染进程接收到消息后与网络进程建立传输数据的“管道”
    • 渲染进程接收完数据后,向浏览器发送“确认提交”
    • 浏览器进程接收到确认消息后更新浏览器界面状态:安全状态、地址栏url、前进后退的历史状态、更新web页面
  • 在渲染阶段通过渲染流水线在渲染进程的主线程和合成线程配合下,完成页面的渲染
    【url输入了之后会发生什么?】最细解法,从输入URL到页面渲染的过程

  • 先将请求回来的数据解压,随后HTML解析器将其中的HTML字节流通过分词器拆分为一个个Token,然后生成节点Node,最后解析成浏览器识别的DOM树结构
    可以通过Chrome调试工具的Console选项打开控制台输入document查看DOM树;

  • 构建CSSOM

  • 样式计算:转换样式表中的属性值,使其标准化。计算DOM树中每个节点的具体样式,这里遵循CSS的继承和层叠规则;可以通过Chrome调试工具的Elements选项的Computed查看某一标签的最终样式;

  • 创建布局树,遍历DOM树中的所有节点,去掉所有隐藏的节点(比如head,添加了display:none的节点),只在布局树中保留可见的节点;

  • 计算布局树中节点的坐标位置;

  • 对布局树进行分层,并生成分层树(Layer Tree),分层树中每一个节点都直接或间接的属于一个图层(如果一个节点没有对应的层,那么这个节点就从属于父节点的图层)

  • 为每个图层生成绘制列表(即绘制指令),并将其提交到合成线程。以上操作都是在渲染进程中的主线程中进行的,提交到合成线程后就不阻塞主线程了;

  • 切分图块:合成线程将图层切分成大小固定的图块(256x256或者512x512)然后优先绘制靠近视口的图块,这样就可以大大加速页面的显示速度;

  • 栅格化操作

  • 合成与显示

    • 合成:一旦所有图块都被光栅化,合成线程就会将它们合成为一张图片,并生成一个绘制图块的命令——“DrawQuad”,然后将该命令提交给浏览器进程。
    • 显示:浏览器进程里面有一个叫viz的组件,用来接收合成线程发过来的DrawQuad命令,然后根据DrawQuad命令,将其页面内容绘制到内存中,最后再将内存显示在屏幕上。

到这里,经过这一系列的阶段,编写好的HTML、CSS、JavaScript等文件,经过浏览器就会显示页面了。

参考博客

一文摸透从输入URL到页面渲染的过程
输入URL全过程

养殖设备