在浏览器输入URL回车之后发生了什么

194 阅读11分钟

一、大致流程

●URL解析

●DNS解析(将输入的域名解析成IP地址)

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

●发送HTTP请求

●服务器处理请求并响应 HTTP 报文

●浏览器接受响应

●渲染页面

●断开连接(TCP 四次挥手)

二、URL 解析

2.1 URL 介绍

URL(Uniform Resource Locator),统一资源定位符,用于定位互联网上资源,俗称网址。比如 www.w3school.com.cn/html/index.…

遵守以下的语法规则:scheme://host.domain:port/path/filename,各部分名次解释如下:

●scheme - 定义因特网服务的类型。常见的协议有 http、https、ftp、file,其中最常见的类型是 http,而 https 则是进行加密的网络传输。

●host - 定义域主机(http 的默认主机是 www)

●domain - 定义因特网域名,比如 w3school.com.cn

●port - 定义主机上的端口号(http 的默认端口号是 80)

●path - 定义服务器上的路径(如果省略,则文档必须位于网站的根目录中)。

●filename - 定义文档/资源的名称

2.2 URL解析流程

地址解析

首先会判断输入的是否是一个合法的URL,还是一个待搜索关键字,所以就需要根据输入的内容进行自动完成,字符编码等操作,一个合法的URL,一定包含协议、域名等信息。

HSTS

由于安全隐患,会使用 HSTS 强制客户端使用 HTTPS 访问页面。

其他操作

浏览器还会进行一些额外的操作,比如安全检查、访问限制(之前国产浏览器限制 996.icu)。

检查缓存

三、 DNS解析

3.1 IP地址

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

3.2 DNS 的概念

ip地址要么是纯数字,要么就是数字加字母(ipv4:104.17.208.102, ipv6: 2060:4700::6811:d166 ),记忆起来实在太难了,于是将ip地址和域名关联起来(www.example.com),在浏览器都是通过输入域名来得到相应的网页内容的,而不是IP地址,但是计算机智能识别并用IP地址定位,于是就需要域名解析道ip地址这个过程。 DNS通过域名查找IP地址,或者逆向从IP地址反查域名的服务。DNS 是一个网络服务器,我们的域名解析简单来说就是在DNS上记录一条信息记录。

3.3 域名结构树

域名结构树最顶部都是由一个点表示的,也就是说域名最终都会汇集到一个根管理,这个根是由13个根域名服务器组成的,这13个根域名服务器是由12个独立运营结构运营的。

服务器之间的关系:

根域名服务器会管理,com、cn、net等这个顶级域名服务器, 顶级域名服务器分别管理各自的权威域名服务器,权威域名服务器对应管理各自的主机。

3.4 DNS 解析过程

浏览器缓存

 浏览器需要看自己的浏览器缓存中有没有对应的ip记录。

操作系统缓存

如果浏览器缓存中找不到需要的 DNS 记录,那就去操作系统中找。操作系统也有自己的 DNS缓存,但在这之前,会向检查域名是否存在本地的 Hosts 文件里,没有则向 DNS 服务器发送查询请求。

路由器缓存

路由器也有自己的缓存。

ISP DNS缓存

ISP 是互联网服务提供商(Internet Service Provider)的简称,ISP 有专门的 DNS 服务器应对 DNS 查询请求。ISP DNS 就是在客户端电脑上设置的首选 DNS 服务器,它们在大多数情况下都会有缓存。

根DNS 服务器查询

ISP 的 DNS 服务器还找不到的话,它就会向根服务器发出请求,进行递归查询(DNS 服务器先问根域名服务器.com 域名服务器的 IP 地址,然后再问.bliliblili 域名服务器,依次类推)在前面所有步骤没有缓存的情况下,本地 DNS 服务器会将请求转发到互联网上的根域,下面这个图很好的诠释了整个流程:

注意:

解析器与本地dns服务器之间用的是递归的方式传输,传输以后回归,意思就是一路查下去中间不返回,得到最终结果才返回信息。而本地服务器与三层服务器之间用的是迭代的方式传输,第一步得到什么然后在用第二步。

四、建立连接

在客户端发送数据之前需要发起 TCP 三次握手建立与服务端的连接,用以同步客户端和服务端的序列号和确认号,并交换 TCP 窗口大小信息。所谓三次握手(Three-way Handshake),是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。

4.1 Tcp 三次握手

(1) 第一次握手:建立连接时,客户端A发送SYN包(SYN=1,同时选择一个初始序列号 seq=x )到服务器B,并进入SYN_SEND状态,等待服务器B确认。

(2) 第二次握手:服务器B收到SYN包,必须确认客户A的SYN=1,同时自己也发送一个SYN包(SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y),即SYN+ACK包,此时服务器B进入SYN_RECV状态。

(3) 第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ack=y+1,自己的序列号seq=Z),此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成。

五、发送HTTP请求

TCP 三次握手结束后,浏览器和服务器就建立了连接,浏览器就会发送 HTTP 请求报文给服务器。请求报文由请求行、请求头、空行和请求数据组成,如下图所示:

●请求行内容

请求方法:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE。

   URL 请求地址: <协议>://<主机>:<端口>/<路径>?<参数> 组成

   协议版本: http 版本号

例如: POST /chapter17/user.html HTTP/1.1

●请求头内容

请求的附加信息: 由键值对组成,每行一对,关键字和值用英文冒号“:”分隔;知道遇到了空行就意味着下面没有请求头部了,

请求头部通知服务器有关于客户端请求的信息。它包含许多有关的客户端环境和请求正文的有用信息。其中比如:Host,表示主机名,虚拟主机;Connection,HTTP/1.1 增加的,使用 keepalive,即持久连接,一个连接可以发多个请求;User-Agent,请求发出者,兼容性以及定制化需求。

●请求体: 承载多个请求参数的数据,包含回车符、换行符和请求数据,并不是所有请求都具有请求数据。

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

响应流程大致如下:

http响应报文:

1.组成 : 响应行(request line)、响应头部(header)、响应主体三个部分组成。如下图所示:

(1) 响应行包含:协议版本,状态码,状态码描述

状态码规则如下:

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

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

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

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

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

(2) 响应头部包含响应报文的附加信息,由 名/值 对组成

(3) 响应主体包含回车符、换行符和响应返回数据,并不是所有响应报文都有响应数据

七、浏览器解析渲染页面

浏览器拿到HTML,先将HTML转换成dom树,再将CSS样式转换成stylesheet,根据dom树和stylesheet创建布局树,对布局树进行分层,为每个图层生成绘制列表,再将图层分成图块,紧接着光栅化将图块转换成位图,最后合成绘制生成页面。

分层的目的: 避免整个页面渲染,把页面分成多个图层,尤其是动画的时候,把动画独立出一个图层,渲染时只渲染该图层就ok,transform,z-index等,浏览器会自动优化生成图层 光栅化目的:页面如果很长但是可视区很小,避免渲染非可视区的样式造成资源浪费,所以将每个图层又划分成多个小个子,当前只渲染可视区附近区域

八、断开连接

8.1  四次挥手

  当数据传送完毕,需要断开 tcp 连接,此时发起 tcp 四次挥手。TCP的连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake)。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。

(1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送(报文段4)。发起方向被动方发送报文,Fin、Ack、Seq,表示已经没有数据传输了。并进入 FIN_WAIT_1 状态。(第一次挥手:由浏览器发起的,发送给服务器,我请求报文发送完了,你准备关闭吧)

  (2)服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号。被动方发送确认报文,Ack、Seq,表示同意关闭请求。此时主动发起方进入 FIN_WAIT_2 状态。(第二次挥手:由服务器发起的,告诉浏览器,我请求报文接受完了,我准备关闭了,你也准备吧)

  (3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A(报文段6)。被动方向发起方发送报文段,Fin、Ack、Seq,请求关闭连接。并进入 LAST_ACK 状态。(第三次挥手:由服务器发起,告诉浏览器,我响应报文发送完了,你准备关闭吧)

  (4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。发起方向被动方发送报文段,Ack、Seq。然后进入等待 TIME_WAIT 状态。被动方收到发起方的报文段以后关闭连接。发起方等待一定时间2MSL未收到回复,则正常关闭。(第四次挥手:由浏览器发起,告诉服务器,我响应报文接受完了,我准备关闭了,你也准备吧)

8.2  为什么连接的时候是三次握手,关闭的时候却是四次握手?

为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

8.3  为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

  虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。

  所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。

  MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

文章参考: 1、《在浏览器输入URL回车之后发生了什么?》www.bbsmax.com/A/obzbjwp3z…

2、《在浏览器输入URL回车之后发生了什么?(超详细版)》 www.bbsmax.com/A/B0zq0N3Zd…