从url输入到页面展示的过程

从url输入到页面展示的过程

小白第一次发布文章,我就发最近写的一个常考面试题吧

当我们在web浏览器的地址栏中输入: www.baidu.com,然后回车,到底发生了什么

过程概览

  1. 对www.baidu.com这个网址进行DNS域名解析,得到对应IP地址
  2. 根据这个IP,找到对应的服务器,发起TCP的三次握手
  3. 建立TCP连接之后发送HTTP协议
  4. 服务器响应HTML代码,浏览器得到HTML代码
  5. 浏览器解析html代码,并且将请求HTML代码的资源(如js、png等)(先得到html代码,才能找到这些资源)
  6. 浏览器对页面进行渲染呈现给用户
  7. 断开连接:TCP四次挥手

PS:

  1. DNS域名解析采用的是 ***递归查询***的方式,过程是,先去本机DNS缓存(host文件)-》找不到就去根域名服务器找-》下一级-》下一级-》…-》直到找到,找到了就返回web浏览器
  2. 为什么HTTP协议要基于TCP实现?TCP是一个端到端的可靠的面向连接的协议,HTTP基于传输层TCP协议不用担心数据传输的各种问题(当发生错误时,会重传)
  3. 最后一步浏览器是如何对页面进行渲染的?
    • 解析html文件构成DOM树
    • 解析css文件构成渲染树
    • 边解析,变渲染
    • JS单线程运行,JS有可能修改DOM结构,意味着JS执行完成前,后续所有资源的下载都是没必要的,所以JS是单线程,会阻塞后续资源下载

域名解析

在浏览器输入网址之后,首先要解析域名,因为浏览器并不能直接通过域名找到对应的服务器,而是要通过IP地址,那就有一个问题 — 计算机既然可以被赋予IP地址,也可以赋予主机名和域名。那为什么不一开始赋予个IP地址?这样就可以省去解析的麻烦。(因为IP地址很难记住)

IP地址

IP地址是指互联网协议地址,是IP Address的缩写。IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机 分配一个逻辑地址,***以此来屏蔽物理地址的差异,***IP地址是一个32位的二进制数,比如127.0.0.1为本机IP。

***域名就相等于IP地址的乔装打扮的伪装者,带着一副面具。它的作用就是便于记忆和沟通一组服务器的地址。***以此域名比IP地址更好记,因此DNS服务器应运而生。

什么域名解析

DNS协议提供域名查找IP地址,或逆向从IP地址反查域名的访问。 *DNS是一个网络服务器,我们的域名解析简单来说就是在DNS上记录一条信息记录。

例如 baidu.com 220.114.23.56(服务器外网IP地址)80(服务器端口号)

浏览器如何通过域名来查询URL对应IP呢

  • 浏览器缓存:浏览器会按照一定的频率缓存DNS记录
  • 操作系统缓存:如果浏览器缓存找不到需要的DNS记录,那就去操作系统找
  • 路由缓存:路由器也有DNS缓存。
  • ISP的DNS服务器:ISP是互联网服务提供商的建成,ISP有专门的DNS服务器对应DNS查询请求。
  • 根服务器:ISP的DNS服务器还找不到的话,它就会向根域名发去请求,进行递归查询(DNS服务器先问域名服务器.com域名服务器的IP地址,然后再问.baidu域名服务器,以此类推)

小结

浏览器通过向DNS服务器发送域名,DNS服务器查询到与域名对应的IP地址,然后返回给浏览器,浏览器再将IP地址打在协议上,同时请求参数也会在协议搭载,然后一并发送给对应的服务器。接下来介绍向服务器发送HTTP请求阶段,HTTP请求分为三个部分:HTTP三次握手、http请求响应信息、关闭TCP连接。

域名解析

TCP三次握手(面试高频)

在客户端发送数据之前会发送TCP三次握手以同步客户端和服务端的序列号和确认号,并交换TCP窗口大小信息。

流程图如下:

TCP三次握手流程图

img

为什么要三次握手

  • 一次握手情况

由于TCP是面向连接的,一次很明显时不可能的,因为客户端发出连接消息后,却没有接收到来自服务端的回应,客户端就无法确定服务端接是否收到了连接请求,当然也就不能确定是否连接成功。

img

  • 两次握手情况

如果客户端想建立连接,给服务器发送了一个连接请求(SYN),但是由于网络中种种情况,导致没有及时到达服务器,这就导致客户端在很长一段时间中没有收到回复消息(ACK),这时客户端又给服务端发送一个SYN,这次发送和接受很顺利,很快就收到了ACK,但是这时之前的SYN终于到了服务端,服务端规规矩矩的为这个SYN申请资源,然后返回ACK。由于之前的SYN已经失效了,所以客户端也不会去理会这个ACK,但是服务端不知道这个SYN已经失效了,一直为他委托着资源,这就造成了资源的浪费。

三次握手的情况:

一发一收的两次握手既然不行,那么三次握手就可以了吗?

  • 在两次握手中服务端不知道当前这个SYN是不是有效的,三次握手就很好的解决了这个问题
  • 第三次握手就是给服务端来回复第二次握手,这也就是说服务端会等第三次握手的到来,如果第三次握手迟迟不来,服务端就可以识别这个SYN是无效的,就会将他的资源释放了。
  • 还有一种情况就是第三次握手由于网络中的种种原因失败了,这时候客户端认为自己已经连接好了,就会给服务端发送数据,***服务端由于没有收到第三次握手,***就会以RST包对客户端响应,收到RST的客户端就知道第三次握手没有成功,就会重新链接,在谢希尔著《计算机网络》第四部中将“三次握手”的目的是 为了防止已失效的连接请求报文突然又传送到了服务端,因而产生错误。

img

小结:

四次握手和两次握手的情况一样,五次握手和三次握手的情况一样,以此类推,奇数次握手的情况与三次握手相同,同理偶数次握手与两次握手一样,所以为了更快的连接,就使用三次握手最合适。

每次握手失败对应的措施:

第一次握手失败:

如果第一次的SYN传输失败,两段都不会申请资源。如果一段时间后之前的SYN发送成功了,这时客户端只会接受他最后的SYN的SYN+ACK回应,其他的一概忽略,服务端也是如此,会将之前多申请的资源释放了。

第二次握手失败:

如果服务端发送的SYN+ACK传输失败,客户端由于没有收到这条响应,不会申请资源,虽然服务端申请了资源,但是迟迟收不到来自客户端的ACK,也会将该资源释放。

第三次握手失败:

如果第三次握手的ACK传输事变,导致服务端迟迟没有收到ACK,就会释放资源,这时候客户端认为自己已经连接好了,就会给服务端发送数据,服务端由于没有收到第三次握手,就会以RST包对客户端响应。但是实际上服务端会因为没有收到客户端的ACK多次发送SYN+ACK,次数是可以设置的,如果最后还是没有收到客户端的ACK,则释放资源。

三次握手过程详解

TCP数据包结构

首先让我们来看一下TCP数据包的结构图
在这里插入图片描述

其中:

  • 数据序号SEQ 32位,TCP为发送的每一个字节都编一个号码,这里存储当前数据包数据第一个字节的序号,如果将字节流看作在两个应用程序间的单向流动,则TCP用顺序号对每个字节进行计数。序号是32bit的无符号数,序号达到2^32-1后又从0开始。在建立一个新的连接时,SYN标志变为1,顺序号字段包含由这个主机选择的该连接的初始顺序号ISN.
  • 确认号 ACK( 32 位), 包含发送确认的一端所期望收到的下一个顺序号。因此,确认序号应当是上次已成功收到数据字节顺序号加 1 。只有 ACK 标志为 1 时确认序号字段才有效。 TCP 为应用层提供全双工服务,这意味数据能在两个方向上独立地进行传输。因此,连接的每一端必须保持每个方向上的传输数据顺序号。
  • TCP 报头长度( 4 位):给出报头中 32bit 字的数目,它实际上指明数据从哪里开始。需要这个值是因为任选字段的长度是可变的。这个字段占4bit ,因此 TCP 最多有 60 字节的首部。然而,没有任选字段,正常的长度是 20 字节
  • 窗口大小( 16 位):数据字节数,表示从确认号开始,本报文的源方可以接收的字节数,即源方接收窗口大小。窗口大小是一个 16bit 字段,因而窗口大小最大为 65535字节
  • SYN:同步序列编号(*Synchronize Sequence Numbers*)。是TCP/IP建立连接时使用的握手信号。在客户机和服务器之间建立正常的TCP网络连接时,客户机首先发出一个SYN消息,服务器使用SYN+ACK应答表示接收到了这个消息,最后客户机再以ACK消息响应。

我们介绍了大概的结构图,因此我们来讲解一下TCP三次握手的过程:

第一次握手

客户主动(active open)去connect服务器,并且SYN(同步序列编号)假设序列化为J,服务器是被动打开(passive open)

第二次握手

服务器在收到SYN后(同步序列编号),它会发送一个SYN以及一个ACK(确认号)给客户,ACK(确认号)的序列化是J+1表示是给SYN J的应答,新发送SYN(同步序列编号) K序列化为K

第三次握手
  • 客户端在收到信SYN(同步序列化) K,ACK(确认码) J+1后,也回应ACK K+1以表示收到了。此包发送完毕,客户端和服务器进入TCP连接状态,完成三次握手。
  • 完成三次握手之后,两边可以进行数据发送数据了。

HTTP请求

首先我们要明确,HTTP请求是怎么组成的?

HTTP请求组成结构

HTTP请求由四部分组成:请求行(request line)、请求头部(headers)、空行(blank line)和请求数据(request body)4个部分组成。

结构如下:

img

请求行

请求行由三个部分组成:

  • 请求方法(GET/POST …)
  • 请求地址URL(如/index.html)
  • 协议版本

例如: GET /index.html HTTP/1.1

注意:它们之间都用空格分隔


资料:请求方法

img

url:

img

请求头部

请求头部为请求报文添加了一些附加信息,由“名/值”对组成,每行一对,名和值之间使用冒号分隔。

请求头部最后会有一个空行,表示请求头部结束,接下来为请求数据。

img

PS:

以键值对存在 但是要注意符号“:”后面有一个空格如 ***Host: localhost:8080 ***

请求数据

​ 请求数据不在GET方法中使用,而在POST方法中使用。POST方法适用于需要客户填写表单的场合。与请求数据相关的最长使用的请求头部是Cntent-Type和Content-Length。下面是一个POST方法的请求报文:例如

POST  /index.php HTTP/1.1    请求行

    Host: localhost

    User-Agent: Mozilla/5.0 (
    Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2  请求头

    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8

    Accept-Language: zh-cn,zh;q=0.5

    Accept-Encoding: gzip, deflate

    Connection: keep-alive

    Referer: http://localhost/

    Content-Length:25

    Content-Type:application/x-www-form-urlencoded

  空行

   username=aa&password=1234  请求数据

HTTP响应

结构图如下图所示

img

HTTP响应报文由

  • 状态行(status line)
  • 响应头部(headers)
  • 空行(blank line)
  • 响应数据

状态行

状态行由3部分组成,分别为:协议版本、状态码、状态码扫描。其中协议版本与请求报文一致,状态码描述是对状态码的简单描述。

img

响应头部

img

响应数据

用于存放需要返回给客户端的数据信息。

例子:

HTTP/1.1 200 OK  状态行

        Date: Sun, 17 Mar 2013 08:12:54 GMT  响应头部

        Server: Apache/2.2.8 (Win32) PHP/5.2.5

        X-Powered-By: PHP/5.2.5

        Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/

        Expires: Thu, 19 Nov 1981 08:52:00 GMT

        Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

        Pragma: no-cache

        Content-Length: 4393

        Keep-Alive: timeout=5, max=100

        Connection: Keep-Alive

        Content-Type: text/html; charset=utf-8

          空行

         

<html>  响应数据

<head>

<title>HTTP响应示例<title>

</head>

<body>

Hello HTTP!

</body>

</html>

浏览器解析HTML代码,并请求HTML代码中的资源

浏览器拿到html文件后,就开始解析其中的html代码,遇到js/css/image等静态资源时,就向服务器端去请求下载(会使用多线程下载,每个浏览器的线程数不一样),这是时候就用上 ***keep-alive***特性了,建立一次HTTP连接,可以请求多个资源,下载资源的顺序就是按照代码里面的顺序,但是由于每个资源大小不一样,而浏览器又是多线程请求请求资源,所以这里显示的顺序并不一定是代码里面的顺序。

关闭TCP连接,浏览器对页面进行渲染呈现给用户

​ 浏最后,浏览器利用自己内部的工作机制,把请求的静态资源和html代码进行渲染,渲染之后呈现给用户

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

JS的解析是由浏览器中的JS解析引擎完成的。JS是单线程运行,JS有可能修改DOM结构,意味着JS执行完成前,后续所有资源的下载是没有必要的,所以JS是单线程,会阻塞后续资源下载

总结

域名解析 --> 发起TCP的3次握手 --> 建立TCP连接后发起http请求 --> 服务器响应http请求,浏览器得到html代码 --> 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) --> 浏览器对页面进行渲染呈现给用户

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值