• 从输入url到页面完成加载发生了什么(完整版)


    在写这篇文章之前本想着这个知识点涉及知识点太多太杂,找一篇大牛写的看看就算了,但是看了大概七八篇后,内心更纠结了——真的好杂。。。记忆点找不到了,搞的心里乱乱的,大概是纠结症犯了。所以还是动手总结一下,让自己有个可以抓取的记忆点,也让自己对这个知识点有个浅显的认知。本文旨在讲述发生的流程,如想深究的可自行度娘哦~,其中穿插的知识点及概念我会放到小框里或者贴参考链接。

    先来个流程总述:

    • DNS解析:将域名解析成IP地址
    • TCP连接:TCP三次握手
    • 发送HTTP请求
    • 服务器处理请求并返回HTTP报文
    • 浏览器解析渲染页面
    • 连接结束:TCP四次挥手

    1、DNS解析

    在浏览器输入URL后,首先要经过域名解析。浏览器通过向 DNS 服务器发送域名,DNS 服务器查询到与域名相对应的 IP 地址,然后返回给浏览器,浏览器再将 IP 地址打在协议上,同时请求参数也会在协议搭载,然后一并发送给对应的服务器。

    1.什么是URL
    URLUniform Resource Locator),统一资源定位符,用于定位互联网上资源,俗称网址。比如 http://www.w3school.com.cn/ht...,
    遵守以下的语法规则:
    `scheme://host.domain:port/path/filename`
    各部分解释如下:
    scheme:定义因特网服务的类型。常见的协议有 httphttpsftpfile,其中最常见的类型是 http,而 https 则是进行加密的网络传输。
    host:定义域主机(http 的默认主机是 wwwdomain:定义因特网域名,比如 w3school.com.cn
    port:定义主机上的端口号(http 的默认端口号是 80path: 定义服务器上的路径(如果省略,则文档必须位于网站的根目录中)。
    filename: 定义文档/资源的名称
    
    2. 什么是DNS
    DNS(domain name system,域名系统):因特网上域名和IP地址相互映射的分布式数据库;简单理解就是域名与IP地址的对照表,因为域名(如:www.google.com)对于我们而言,更便于记忆,但是机器却不擅长这种表达方式,因此需要将域名转换为IP地址,以便于机器识别, 这便有了DNS3. 根域名服务器
    根服务器是架设互联网的必须设施,管理互联网的主目录,全球共有13套根域名服务器
    
    4. 递归查询
    客户端主机向本地域名服务器的查询是递归查询;所谓递归查询:客户端主机查询的域名地址无法在本地域名服务器中找到,因此本地域名服务器就以DNS客户端的身份向其他根域名服务器发起请求,进行查询,而不是让客户端主机去一直查询;
    递归查询的结果要么是返回的IP地址,要么是报错,表示无法查询到地址;
    
    5. 迭代查询
    本地域名服务器向根服务器、顶级域名服务器和主机域名服务器发起的查询请求就是迭代的过程,如:本地域名服务器向根服务器发起查询请求,根服务器中会告诉本地域名服务器:”我这里没有你要找的内容,你去顶级域名服务器上找吧“,并将顶级域名服务器的地址返回给本地域名服务器,本地域名服务器接收到后,继续向顶级域名服务器发送请求;顶级域名服务器要么返回ip地址,要么告诉本地域名服务器下一步要向哪个权限域名服务器发送请求,直到找到ip地址或找不到ip返回报错信息,然后信息返回给客户端主机;
    下图给出了这两种查询的差别
    
    递归过程:主机→本地DNS服务器→其他DNS服务器(如:我要找一个苹果吃,找到了A,问A有没有,A说我帮你去找BB可能有,果真B有,然后B将苹果给了AA再将苹果给我,这就是递归)
    迭代过程:本地DNS服务器→根服务器,本地DNS服务器→顶级域名服务器,本地DNS服务器→权限域名服务器;(如:我要找一个苹果,找到了AA说我也没有,B可能有,你去找B吧;我又找BB说我也没有,你去找C吧,我又去找C,终于找到了苹果,这就是迭代的过程)
    复制代码

    2、TCP连接:TCP三次握手

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

    在这里插入图片描述

     说明:
        Ack:应答
        Fin:结束; 结束会话
        Seq: 一个数据段的第一个序列号
        SYN: 同步; 表示开始会话请求
    复制代码
    • 第一次握手:客户端A将标志位SYN置为1,随机产生一个值为seq=X(X的取值范围为=1234567)的数据包到服务器,客户端A进入SYN_SENT状态,等待服务端B确认(第一次握手,由浏览器发起,告诉服务器我要发送请求了);
    • 第二次握手:服务端B收到数据包后由标志位SYN=1知道客户端A请求建立连接,服务端B将标志位SYN和ACK都置为1,ack=X+1,随机产生一个值seq=Y,并将该数据包发送给客户端A以确认连接请求,服务端B进入SYN_RCVD状态(第二次握手,由服务器发起,告诉浏览器我准备接受了,你赶紧发送吧)。
    • 第三次握手:客户端A收到确认后,检查ack是否为X+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=Y+1,并将该数据包发送给服务端B,服务端B检查ack是否为Y+1,ACK是否为1,如果正确则连接建立成功,客户端A和服务端B进入ESTABLISHED状态,完成三次握手,随后客户端A与服务端B之间可以开始传输数据了(第三次握手,由浏览器发送,告诉服务器,我马上就发了,准备接受吧)。

    为什需要三次握手? 计算机网络》第四版中讲“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。 书中的例子是这样的,“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。 假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”。主要目的防止server端一直等待,浪费资源。

    3、浏览器向web服务器发送HTTP请求

    TCP三次握手之后,开始发送HTTP请求报文至服务器(关于HTTP请求报文详解,我单独写了一篇☞传送门

    HTTP请求报文格式:请求行+请求头+空行+消息体,请求行包括请求方式(GET/POST/DELETE/PUT)、请求资源路径(URL)、HTTP版本号;

    4、服务器处理请求并返回HTTP报文

    服务器收到请求后会发出应答,即响应数据。HTTP响应与HTTP请求相似, HTTP响应报文格式:状态行+响应头+空行+消息体,状态行包括HTTP版本号、状态码、状态说明。

    5、浏览器解析渲染页面

    浏览器拿到响应文本后,解析HTML代码,请求js,css等资源,最后进行页面渲染,呈现给用户。页面渲染一般分为以下几个步骤:

    (1)根据HTML文件解析出DOM Tree

    (2)根据CSS解析出 CSSOM Tree(CSS规则树)

    (3)将 DOM Tree 和 CSSOM Tree合并,构建Render tree(渲染树)

    (4)reflow(重排):根据Render tree进行节点信息计算(Layout)

    (5)repaint(重绘):根据计算好的信息绘制整个页面(Painting)

    6、TCP四次挥手。

    当数据传输完毕,需要断开TCP连接,此时发起tcp四次挥手

    1、客户端向服务端发送报文,Fin、Ack、Seq,表示已经没有数据传输了。并进入 FIN_WAIT_1 状态。(由浏览器告诉服务器,我请求报文发送完了,你准备关闭吧)

    2、服务端向客户端发送报文,Ack、Seq,表示同意关闭请求。此时主机发起方进入 FIN_WAIT_2 状态。(由服务器告诉浏览器,我请求报文接受完了,我准备关闭了,你也准备吧)

    3、服务端向客户端发送报文段,Fin、Ack、Seq,请求关闭连接。并进入 LAST_ACK 状态。(由服务器告诉浏览器,我响应报文发送完了,你准备关闭吧)

    4、客户端向服务端发送报文段,Ack、Seq。然后进入等待 TIME_WAIT 状态。被动方收到发起方的报文段以后关闭连接。发起方等待一定时间未收到回复,则正常关闭。(由浏览器告诉服务器,我响应报文接受完了,我准备关闭了,你也准备吧)

    简单说就是:

    1、A——>B :A告诉B:“我发完了”;

    2、B——>A:B告诉A:“好的,我知道你发完了”

    3、B——>A:B告诉A:“我收完了”;

    4、A——>B:A告诉B:“好的,我知道你发收完了”

    后话

    以上基本就是在地址栏从输入 URL 到页面加载显示发生的全过程,当然还有很多的细节没有写进去,不过这些知识对于前端来说已经足够了,有兴趣的小伙伴可以自行深究。最后,小生乃前端小白一枚,写文章的最初衷是为了让自己对该知识点有更深刻的印象和理解,写的东西也很小白,文中如有不对,欢迎指正~ 然后就是希望看完的朋友可以点个喜欢,也可以关注一波~ 我会持续输出!

    个人博客链接

    GitHub

    CSDN个人主页

    掘金个人主页

    简书个人主页

    来源:https://juejin.cn/post/6844904122206912526
  • 相关阅读:
    Unique Binary Search Trees——LeetCode
    Binary Tree Inorder Traversal ——LeetCode
    Maximum Product Subarray——LeetCode
    Remove Linked List Elements——LeetCode
    Maximum Subarray——LeetCode
    Validate Binary Search Tree——LeetCode
    Swap Nodes in Pairs——LeetCode
    Find Minimum in Rotated Sorted Array——LeetCode
    Linked List Cycle——LeetCode
    VR AR MR
  • 原文地址:https://www.cnblogs.com/konglxblog/p/16758310.html
Copyright © 2020-2023  润新知