浏览器输入url回车后,会发生什么?

通常我们想访问某一个网址,我们会在浏览器中输入它的域名,然后点击回车进行跳转,这样就可以进到网站的主页,看似简单的两步,其实背后都需要大量的代码在运行,支持,才能完成!那浏览器到底都做了哪些事呢?

一、解析URL

回车键按下,OS返回给浏览器一个“按键按下”事件,浏览器开始解析URL,通过URL,浏览器能够知道以下信息:

  1. 传送协议 (如:http 或者 https)
  2. 服务器(通常为域名,也可以是IP地址)
  3. 端口号(比如“:80”) 
  4. 请求资源页
  5. 查询参数

如果协议或者域名不合法,浏览器会当作关键字搜索,将它交给默认的搜索引擎,反之表示这是一个正常的URL,可以进行跳转。

二、DNS查询

url得到了,接下来要根据url得到目标主机的IP地址才能访问,浏览器首先会查看域名是否在自己的缓存中,如果缓存没有,则查看本地host文件,如果host文件也没有找到,它将会向DNS服务器发送一条DNS查询请求,并返回我们目标主机的IP地址。

DNS解析

具体DNS流程如上,百科一下都有而且很详细。

三、TCP连接

当浏览器得到了目标服务器的 IP 地址,以及 URL 中给出来端口号(http 协议默认端口号是 80, https 默认端口号是 443),它会调用系统库函数 socket ,请求一个 TCP流套接字,对应的参数是 AF_INET/AF_INET6 和 SOCK_STREAM 。

这个请求首先被交给传输层,在传输层请求被封装成 TCP segment。目标端口会被加入头部,源端口会在系统内核的动态端口范围内选取(Linux下是ip_local_port_range)

TCP segment 被送往网络层,网络层会在其中再加入一个 IP 头部,里面包含了目标服务器的IP地址以及本机的IP地址,把它封装成一个IP packet。

这个 TCP packet 接下来会进入链路层,链路层会在封包中加入 frame 头部,里面包含了本地内置网卡的MAC地址以及网关(本地路由器)的 MAC 地址。

到了现在,TCP 封包已经准备好了,下面就是连接和发送。

三次握手:

TCP三次握手

  • 客户端选择一个初始序列号(ISN),将设置了 SYN 位的封包发送给服务器端,表明自己要建立连接并设置了初始序列号
  • 服务器端接收到 SYN 包,如果它可以建立连接:
    • 服务器端选择它自己的初始序列号
    • 服务器端设置 SYN 位,表明自己选择了一个初始序列号
    • 服务器端把 (客户端ISN + 1) 复制到 ACK 域,并且设置 ACK 位,表明自己接收到了客户端的第一个封包
  • 客户端通过发送下面一个封包来确认这次连接:
    • 自己的序列号+1
    • 接收端 ACK+1
    • 设置 ACK 位

三次握手结束,开始发送数据包:

  • 数据通过下面的方式传输:
  • 当一方发送了N个 Bytes 的数据之后,将自己的 SEQ 序列号也增加N
  • 另一方确认接收到这个数据包(或者一系列数据包)之后,它发送一个 ACK 包,ACK 的值设置为接收到的数据包的最后一个序列号

四次挥手:

TCP四次挥手

  • 要关闭连接的一方Client发送一个 FIN 包,表示自己数据已经发送完了
  • Server发送ACK报文确认这个 FIN 包,但此时可能并不会关闭
  • Server确认数据发送完毕,发送一个FIN包,表示自己数据发送结束
  • Client发送ACK报文确认

四、TLS 握手

  • 客户端发送一个 ClientHello 消息到服务器端,消息中同时包含了它的 Transport Layer Security (TLS) 版本,可用的加密算法和压缩算法。
  • 服务器端向客户端返回一个 ServerHello 消息,消息中包含了服务器端的TLS版本,服务器所选择的加密和压缩算法,以及数字证书认证机构(Certificate Authority,缩写 CA)签发的服务器公开证书,证书中包含了公钥。客户端会使用这个公钥加密接下来的握手过程,直到协商生成一个新的对称密钥
  • 客户端根据自己的信任CA列表,验证服务器端的证书是否可信。如果认为可信,客户端会生成一串伪随机数,使用服务器的公钥加密它。这串随机数会被用于生成新的对称密钥
  • 服务器端使用自己的私钥解密上面提到的随机数,然后使用这串随机数生成自己的对称主密钥
  • 客户端发送一个 Finished 消息给服务器端,使用对称密钥加密这次通讯的一个散列值
  • 服务器端生成自己的 hash 值,然后解密客户端发送来的信息,检查这两个值是否对应。如果对应,就向客户端发送一个 Finished 消息,也使用协商好的对称密钥加密
  • 从现在开始,接下来整个 TLS 会话都使用对称秘钥进行加密,传输应用层(HTTP)内容

五、HTTP请求

tcp建立连接后,浏览器发送请求报文,http请求报文分为三块:

  • 请求行:包括请求方法,协议版本,以及url地址    

  • 请求头:包括一些浏览器的设置和内容缓存的信息

 

  • 请求体:和请求头直接隔一个空行,这个空行表示request heard结束,下面是请求体内容,包含一些要查询的信息等

然后是服务端的相应报文,和请求报文一样分为三部分:

  • 响应行:包括状态码和协议版本

状态码:

    • 1xx:指示信息–表示请求已接收,继续处理。

    • 2xx:成功–表示请求已被成功接收、理解、接受。

    • 3xx:重定向–要完成请求必须进行更进一步的操作。

    • 4xx:客户端错误–请求有语法错误或请求无法实现。

    • 5xx:服务器端错误–服务器未能实现合法的请求。

  • 响应头:包含一些连接的信息

  • 响应体:包含返回给浏览器的一些文本信息,通常html,css,js,图片就放在这里

六、浏览器渲染页面

浏览器是一边解析一边渲染的过程,首先是解析HTML文件构成DOMTree(一个页面的结构),然后解析CSS文件构建CSSTree(页面的样式),之后是将这两部分整合RenderTree渲染到页面,这个过程比较复杂,涉及到两个概念: reflow(回流)和repain(重绘)。DOM节点中的各个元素都是以盒模型的形式存在,这些都需要浏览器去计算其位置和大小等,这个过程称为relow;当盒模型的位置,大小以及其他属性,如颜色,字体,等确定下来之后,浏览器便开始绘制内容,这个过程称为repain。页面在首次加载时必然会经历reflow和repain。reflow和repain过程是非常消耗性能的,尤其是在移动设备上,它会破坏用户体验,有时会造成页面卡顿。所以我们应该尽可能少的减少reflow和repain。还有就是页面在加载过程中,遇到js文件,会停止渲染,直到js加载结束,这样也会影响性能,所以我们应该将js放在页面最后加载!

 

你看一晃便是一年,匆匆又是一个春天!

写于工作满一年!

Lan XU

2019/03/04

 

posted on 2019-03-04 17:01  LanXu  阅读(758)  评论(0编辑  收藏  举报

导航