从在浏览器中输入URL到页面渲染出来的完整过程是怎样的?

简介: 域名解析、建立连接、发送请求、响应数据、关闭连接


从宏观上看,主要包括以下几个步骤:域名解析、建立连接、发送请求、响应数据、关闭连接。下面以在Chrome浏览器中输入https://yq.aliyun.com/articles/580962为例,讨论请求的完整过程。

 

  域名解析

1   域名解析流程

bcf78eea64c1771e74887e47304149db35377688

此图为域名解析整体流程,任何一步解析成功,则放弃后续的解析过程。

2   搜索浏览器DNS缓存

浏览器首先搜索浏览器自身的DNS缓存(缓存时间比较短,大概只有1分钟,且只能容纳1000条缓存),看是存在yq.aliyun.com对应的缓存数据而且没有过期,如果找到且未过期的数据,则解析结束。

Chrome中可以使用chrome://net-internals/#dns来进行查看浏览器DNS缓存。如下所示:

2e945af92c68212b44e13383f70e90f275fda8b8

 

3   搜索操作系统的DNS缓存

如果在浏览器的缓存中没有找到有效的数据,那么Chrome会搜索操作系统自身的DNS缓存,如果找到未过期的数据,则解析结束。

Window查看DNS缓存,命令行下使用ipconfig /displaydns 来进行查看。

Mac查看DNS缓存,见:How to view DNS cache in OSX?

Linux查看DNS缓存,见:Linux 如何查看修改DNS配置

 

4   尝试读取hosts文件

如果DNS缓存也没有找到,那么尝试读取hosts文件;查找此域名是否有对应的IP地址,如果找到,则解析结束。

Window中位置:C:\Windows\System32\drivers\etc\hosts目录下。

Mac中位置:/etc/hosts

Linux中位置:/etc/hosts

 

5   向DNS服务器发起域名解析请求

浏览器向本地配置的首选DNS服务器(一般是电信运营商提供的,也可以使用像Google提供的DNS服务器)发起域名解析请求。具体来说是通过UDP协议向DNS服务器的53端口发起请求,这个请求是递归的请求,也就是运营商的DNS服务器必须得提供给我们该域名的IP地址。具体过程如下:

运营商的DNS服务器首先查找自身的缓存,如果找到且未过期,则解析成功。

由运营商的DNS发起迭代DNS解析请求:

运营商的DNS服务器都内置13台根域的DNS服务器的IP地址,它首先会向根域DNS服务器其发起请求(询问yq.aliyun.com这个域名的IP地址是多少啊?)。

根域DNS服务器发现这是一个顶级域com域的一个域名,于是就告诉运营商的DNS服务器com域的IP地址,你去找它com域询问,于是运营商的DNS就得到com域的IP地址。

接着运营商的DNS服务器向com域的服务器发起请求,(询问yq.aliyun.com这个域名的IP地址是多少啊?),com域服务器告诉运营商的DNS服务器aliyun.com的ip地址,你去询问他们,于是运营商的DNS就得到aliyun.com域的IP地址。

接着运营商的DNS服务器向aliyun.com域名的DNS服务器(这个一般就是由域名注册商提供的,如万网,新网等)发起请求(询问yq.aliyun.com这个域名的IP地址是多少啊?),aliyun.com域名的DNS服务器查到域名yq.aliyun.com,返回ip地址给运营商的DNS服务器。

运营商的DNS服务器就拿到了yq.aliyun.com这个域名对应的IP地址后返回给浏览器,终于浏览器拿到了yq.aliyun.com对应的IP地址。

 

6   特殊情况

Win系统中,如果经过以上的4个步骤,还没有解析成功,那么会进行如下步骤:

操作系统就会查找NetBIOS name Cache(NetBIOS名称缓存,就存在客户端电脑中的),凡是最近一段时间内和我成功通讯的计算机的计算机名和Ip地址,就都会存在这个缓存里面。如果该名称正好是几分钟前和我成功通信过,那么这一步就可以成功解析。

如果还是未解析成功,那会查询WINS 服务器(是NETBIOS名称和IP地址对应的服务器)

如果还没有成功,那么客户端就要进行广播查找。

如果还没有成功,那么客户端就读取LMHOSTS文件(和HOSTS文件同一个目录下,写法也一样)。

如果还没有解析成功,那么就宣告这次解析失败,那就无法跟目标计算机进行通信。

注意:一般情况下是不会进行这几步的,更多信息可以参考《NetBIOS协议和NBNS协议》。

 

  建立连接

经历上面的域名解析过程以后,我们会得到服务器的ip,那么接下来要做的就是和服务器建立连接。

1   建立连接流程

获取IP地址之后,User-Agent(一般是指浏览器)会以一个随机端口(1024<端口< 65535)向服务器的WEB程序(常用的有httpd,nginx等)80端口发起TCP的连接请求。

这个连接请求(原始的http请求经过TCP/IP4层模型的层层封包)到达服务器端后,进入到网卡,然后是进入到内核的TCP/IP协议栈(用于识别该连接请求,解封包,一层一层的剥开),还有可能要经过Netfilter防火墙(属于内核的模块)的过滤,最终到达WEB程序,最终建立了TCP/IP的连接。

2   TCP报文

b892173344e7a3e8ed1ca7a3a233219c20a002f6

以上为TCP的报文格式,接下来我们讨论与建立连接相关的几项内容。

标志位:标志位共6个,分别为URG、ACK、PSH、RST、SYN、FIN,含义如下:

URG:紧急指针(urgent pointer)有效。

ACK:确认序号有效。

PSH:接收方应该尽快将这个报文交给应用层。

RST:重置连接。

SYN:发起一个新连接。

FIN:释放一个连接。

序号:Sequence Number,简称seq,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。

确认序号:Acknowledgment Number,简称ack,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。

 

3   三次握手建立连接

0fbb631459a8f3758c6a67d91d1c1f80ab09ecb1

第一次握手:Client设置SYN=1,随机产生一个值seq=m,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。

第二次握手:Server收到数据包,通过标志位SYN=1知道Client请求建立连接,Server设置标志位SYN=1、ACK=1,设置ack=m+1,随机产生一个值seq=n,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。

第三次握手:Client收到确认后,检查ack=m+1、ACK=1是否成立,如果是则设置标志位ACK=1、ack=n+1,并将该数据包发送给Server,此时Client状态为ESTABLISHED;Server收到数据包后检查ack=n+1、ACK=1是否成立,如果是则连接建立成功,Server也进入ESTABLISHED状态。

  发送请求

1   发送请求

完成三次握手,连接建立后,Client与Server之间就可以开始传输数据了。客户端根据HTTP协议的规范,发送请求到服务端。发送请求的整个过程只需要按照协议规范,并遵守浏览器同源策略,基本上就可以正常请求了。一般稍有WEB开发经验的人对这一块内容都不会陌生,所以这里就不过多讨论。

2   CDN缓存

大部分网页中都存在很多图片、CSS、JS等静态文件,为了节省流量、提高响应速度,一般都会采用CDN缓存。

在网站和用户之间加入CDN以后,用户不会有任何与原来不同的感觉。一个典型的CDN用户访问调度流程如下所示:

fe679554b17aee19410c1d6c9a7638bcc938f71e

当请求一个URL时,首先通过DNS服务器进行域名解析(见1),DNS系统会将域名的解析权交给CNAME指向的CDN专用的DNS服务器(见2)。

CDN的DNS服务器将CDN的全局负载均衡设备的IP地址返回用户(见3)。

用户向CDN的全局负载均衡设备发起访问请求(见4)。

CDN全局负载均衡设备根据用户IP地址,以及用户请求的URL,选择一台用户所属区域的区域负载均衡设备,告诉用户向这台设备发起请求(见5)。

区域负载均衡设备会为用户选择一台合适的缓存服务器提供服务(见6),选择的依据包括:根据用户IP地址,判断哪一台服务器距用户最近;根据用户所请求的URL中携带的内容名称,判断哪一台服务器上有用户所需内容;查询各个服务器当前的负载情况,判断哪一台服务器尚有服务能力。基于以上这些条件的综合分析之后,区域负载均衡设备会向全局负载均衡设备返回一台缓存服务器的IP地址。

全局负载均衡设备把服务器的IP地址返回给用户(见7)。

用户向缓存服务器发起请求,缓存服务器响应用户请求,将用户所需内容传送到用户终端(见8)。

如果这台缓存服务器上并没有用户想要的内容,而区域均衡设备依然将它分配给了用户,那么这台服务器就要向它的上一级缓存服务器请求内容,直至追溯到网站的源服务器将内容拉到本地。

 

  响应数据

假设服务端的架构是,请求先到达nginx服务器,然后转发到Tomcat服务器。

Nginx收到用户请求以后,取请求头信息,首先进行Host匹配,接着进行server和location匹配;匹配后进行业务处理,例如:直接返回html页面、转发到底层Java应用服务器,等等。

Tomcat服务器收到转发过来的请求以后,先匹配应用名,没有应用名,则匹配/;再匹配RequestMapping,即/articles/580962;如果匹配上,那么进入对应的RequestMapping进行业务逻辑处理。

业务处理完了以后,通过连接将处理结果返回给客户端。

 

  渲染数据

1   浏览器渲染

客户端收到响应数据以后先解析HTML内容,如果遇到JS、CSS、图片等资源时,通过多线程去下载这些资源,具体线程数有浏览器决定。

2   Keep-alive

当使用非KeepAlive模式时,每个请求/应答客户和服务器都要新建一个连接,完成之后立即断开连接(HTTP协议为无连接的协议);

当使用Keep-Alive模式(又称持久连接、连接重用)时,Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接。

http 1.0中默认是关闭的,需要在http头加入"Connection: Keep-Alive"才能启用Keep-Alive;http 1.1中默认启用Keep-Alive,如果加入"Connection: close",才关闭。

3   响应状态码

以下浏览器加载一个页面内容的请求数据截图,其中两种响应状态码200、304。

dd75ee64c3de757d16d26115f9827cdd66880d98

200:服务端正常响应内容。

304:自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容,此时可以从本地缓存中获取数据,如下图所示。2ab1b5946ce891ad1a0cc9ee84f0455d3f8f2db0

更多状态码含义,请参考HTTP状态码说明。

 

  关闭连接

数据交互完成以后,需要关闭连接,回收资源。

1   全双工连接

由于TCP连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。

首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,大多数场景中,客户端是主动关闭方。

 

2   四次挥手关闭连接

ec140ec1a72eda3b51ea8716d7be2d98cabdb428

第一次挥手:Client发送数据报(FIN=1、seq=随机序号m)到服务端,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。

第二次挥手:Server收到FIN=1的数据报以后,发送一个响应数据报(ACK=1、ack=m+1)给Client,Server进入CLOSE_WAIT状态,Client收到数据以后校验ack信息,校验通过进入FIN_WAIT_2状态。

第三次挥手:Servert发送数据报(FIN=1、seq=随机序号n)到客户端,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。

第四次挥手:Client收到FIN=1的数据报以后,发送一个响应数据报(ACK=1、ack=n+1)给服务端,Client进入TIME_WAIT状态,Server收到数据报以后,校验ack信息,通过则进入CLOSED状态,完成四次挥手。

 

  参考文档

浏览器中输入域名以后的完整过程

http://blog.csdn.net/hujunqi/article/details/49334439

 

CDN的基本工作过程

http://book.51cto.com/art/201205/338756.htm

 

 

 

 

 

相关文章
|
1月前
|
缓存 JavaScript
vue阻止浏览器刷新和关闭页面提示
使用场景:在使用vuex进行缓存管理时,页面的缓存会随着页面关闭而消失,如果缓存动作仍在进行中,关闭页面会导致数据丢失,此时需要阻止页面关闭
41 3
|
2月前
|
数据采集 Web App开发 JSON
浏览器插件:WebScraper基本用法和抓取页面内容(不会编程也能爬取数据)
本文以百度为实战案例演示使用WebScraper插件抓取页面内容保存到文件中。以及WebScraper用法【2月更文挑战第1天】
115 2
浏览器插件:WebScraper基本用法和抓取页面内容(不会编程也能爬取数据)
|
2月前
|
缓存 网络协议 前端开发
当浏览器输入url的时候会发生什么?
当浏览器输入url的时候会发生什么?
47 0
|
10天前
【超实用】Angular如何修改当前页面网页浏览器url后面?param1=xxx&param2=xxx参数(多用于通过浏览器地址参数保存用户当前操作状态的需求),实现监听url路由切换、状态变化。
【超实用】Angular如何修改当前页面网页浏览器url后面?param1=xxx&param2=xxx参数(多用于通过浏览器地址参数保存用户当前操作状态的需求),实现监听url路由切换、状态变化。
|
10天前
|
JavaScript
【归总】原生js操作浏览器hash、url参数参数获取/修改方法合集
【归总】原生js操作浏览器hash、url参数参数获取/修改方法合集
|
1月前
|
Web App开发 缓存 网络协议
|
2月前
|
消息中间件 JavaScript 前端开发
前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理)
前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理)
|
3月前
|
域名解析 缓存 JavaScript
url是怎么进行渲染的?
url是怎么进行渲染的?
21 0
|
3月前
|
前端开发 JavaScript 数据可视化
探索浏览器的内心世界:渲染机制的奥秘
探索浏览器的内心世界:渲染机制的奥秘
探索浏览器的内心世界:渲染机制的奥秘
|
3月前
|
搜索推荐 前端开发 UED
html页面实现自动适应手机浏览器(一行代码搞定)
html页面实现自动适应手机浏览器(一行代码搞定)
56 0

热门文章

最新文章