在地址栏输入一个url到页面加载都经历了什么?

当我们在浏览器网址中输入一个地址,点击回车后发生了以下事情。分为两种情况,http事务和https事务。先讲http事务:

1、浏览器(客户端)进行了地址解析。

2、将解析出的域名进行dns解析。

3、通过ip寻址和arp,找到目标(服务器)地址。

4、进行tcp三次握手,建立tcp连接。

5、浏览器发送数据,等待服务器响应。

6、服务器处理请求,并对请求做出响应。

7、浏览器收到服务器响应,得到html代码。

8、渲染页面。

通过以上这些步骤,就完成了一次完整的http事务。下面,将详细的讲述每一个步骤发生了什么。

    一、浏览器(客户端)进行了地址解析。

当我们在浏览器中输入一个地址,按下回车后,浏览器获取到的是一个字符串。浏览器此时要对这个地址进行解析,获取协议,主机,端口,路径等信息。

例如: 

http://www.imooc.com/article/draft/id/430 这个网址缺少了一些东西,端口号,用户名,密码,query和flag都没有。这些东西都是非必须的,甚至协议、路径都可以不要,最简洁的方式为imooc.com,浏览器会对一些默认的东西进行补齐。例如:互联网url默认端口号为80,浏览器默认补齐功能会补齐协议http,有些还会直接在域名前面补上www。所以实际上,即使我们输入的是imooc.com,然而实际访问的却是http://www.imooc.com。

    二、将解析出的域名进行dns解析。

第一步地址解析中我们已经获取到服务器的域名。此时就需要将域名换成对应的ip地址,这就是dns解析。dns解析分为以下几个步骤:

1、先查看浏览器dns缓存中是否有域名对应的ip。

2、如果没有,则看操作系统dns缓存中是否有对应的ip(例如windows的hosts文件)。

3、依旧没有就对本地区的dns服务器发起请求,

4、如果还是没有,就直接到Root Server域名服务器请求解析。

这里面有几点需要关注:

<1>、DNS在进行区域传输的时候使用TCP协议,其它时候则使用UDP协议;

<2>、全球只有十三台**逻辑**根服务器, 其中任何一次解析成功就返回对应的ip地址。

    三、通过ip寻址和arp,找到目标(服务器)地址。

第二步获取到了ip,此时直接通过ip寻址找到ip对应的服务器,然后通过arp协议找到服务器的mac地址。

这里有几点需要注意:

1、ip地址(ipv4, 32位)。ip地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。ip地址分为A、B、C、D、E五大类:

A类地址:一个字节(8位)的网络地址和三个字节的主机地址。地址范围为:1.0.0.0~126.255.255.255。

B类地址:二个字节的网络地址和二个字节的主机地址。地址范围为:128.0.0.0~191.255.255.255。

C类地址:三个字节的网络地址和一个字节的主机地址。地址范围为:192.0.0.0~223.255.255.255。

D类地址:D类地址用于多点广播(Multicast),D类IP地址第一个字节以“lll0”开始,它是一个专门保留的地址。地址范围为:224.0.0.0~239.255.255.255。

E类地址: E类IP地址 以“llll0”开始,为将来使用保留。地址范围为:240.0.0.0~255.255.255.254。,255.255.255.255用于广播地址。

其中缺失了两部分,一个是0开头的,“0”表示该地址是本地主机,不能传送。一个是127开头的,127开头的是网卡自身,常用于测试。这里为什么是十进制的数字,为什么中间有‘.’,其实这都是为了方便人类而人为加上去的。转化为计算机语言就是二进制的,每一个字节八位,八位二进制能表示的最大数字就是255,这样ip地址就齐全了。可能有些人还发现ip地址为 10.170.8.61/23 ,这里涉及到局域网、保留地址和子网掩码。这里的意思是,前23位表示为该台主机的网络地址,该网络有 2^(32-23) = 512台主机。具体就不展开讲了,涉及的内容太深,太多。<--感兴趣的可以参考-->

2、IP寻址如何工作?

ip寻址主要有两种方式,一种是同一网段,一种是不同网段。要判断两个IP地址是不是在同一个网段,就将它们的IP地址分别与子网掩码做与运算,得到的结果一网络号,如果网络号相同,就在同一子网,否则,不在同一子网。

同一网段的情况:

主机A和主机B,首先主机A通过本机的hosts表或者wins系统或dns系统先将主机B的计算机名  转换为Ip地址,然后用自己的 Ip地址与子网掩码计算出自己所出的网段,比较目的主机B的ip地址与自己的子网掩码,发现与自己是出于相同的网段,于是在自己的ARP缓存中查找是否有主机B 的mac地址,如果能找到就直接做数据链路层封装并且通过网卡将封装好的以太网帧发送有物理线路上去:如果arp缓存中没有主机B的的mac地址,主机A将启动arp协议通过在本地网络上的arp广播来查询主机B的mac地址,获得主机B的mac地址厚写入arp缓存表,进行数据链路层的封装,发送数据。

不同网段的情况:

不同的数据链路层网络必须分配不同网段的Ip地址并且由路由器将其连接起来。和上面一样,主机A发现和主机B不在同一个网段,于是主机A将知道应该将次数据包发送给自己的缺省网关,即路由器的本地接口。主机A在自己的ARP缓存中查找是否有缺省网关的MAC地址,如果能够找到就直接做数据链路层封装并通过网卡 将封装好的以太网数据帧发送到物理线路上去,如果arp缓存表中没有缺省网关的Mac地址,主机A将启动arp协议通过在本地网络上的arp广播来查询缺省网关的mac地址,获得缺省网关的mac地址后写入arp缓存表,进行数据链路层的封装,发送数据。数据帧到达路由器的接受接口后首先解封装,变成ip数据包,对ip 包进行处理,根据目的Ip地址查找路由表,决定转发接口后做适应转发接口数据链路层协议帧的封装,并且发送到下一跳路由器,次过程继续直至到达目的的网络与目的主机。整个过程有点像dns解析,只是dns服务器换成了下一跳路由器,udp编程了tcp,其他差别不大。

3、arp。arp就是地址转化协议,也就是把ip地址转化为mac地址。和dns很像,先查缓存,然后查路由器。

4、mac地址。mac地址就是计算机的物理地址,每个网卡出厂时,被生产厂家烧制在网卡上。采用十六进制数表示,共六个字节(48位)。三个字节是由IEEE的注册管理机构RA负责给不同厂家分配的代码(高位24位),也称为“编制上唯一的标识符”(Organizationally Unique Identifier),后三个字节(低位24位)由各厂家自行指派给生产的适配器接口,称为扩展标识符(唯一性)。如何修改mac地址呢?一个方法就是直接修改网卡上烧制的mac地址,自己烧制。这个基本不靠谱,失误性也高。另一个方法就是修改注册表中的mac地址,因为网络中访问的mac地址都是访问的注册表中的mac地址,不会直接访问网卡。这个比较简单直接。

5、为什么有了ip地址,还要mac地址?这个问题很关键,就像是我有驾驶证了你非要让我提供身份证。这个涉及一些历史问题,因为一开始没有互联网的时候就只有mac地址,还不存在ip地址。后来互联网越来越大之后,发现mac地址找起来太麻烦,并且耗时也越来越久,就发明了ip地址。并且mac地址在一个局域网中还是很有用的,所以就两个一起存在了。详细的信息,<--大家可以参考-->

四、进行tcp三次握手,建立tcp连接。

tcp三次握手的细节,如果还不清晰的朋友可以移步[http你不得不知道的那些事(八)--TCP三次握手][1]。简述一下,第三步我们找到了目标ip,并获得了服务器ip的mac地址。此时浏览器就会请求和服务器连接,用来传输数据。tcp 是稳定双向面向连接的,断开时也会分两边分别断开。面向连接不是说tcp一个双方一直开着的通道,而是维持一个连接的状态,让它看起来有连接。

    五、浏览器发送数据,等待服务器响应。

第四步已经建立了连接,此时就要发送数据了。浏览器会对请求进行包装,包装成请求报文。请求报文的格式如下:
起始行:如 GET / HTTP/1.0 (请求的方法  请求的URL 请求所使用的协议)
头部信息:User-Agent  Host等成对出现的值

主体

请求头部和主体之间有一个回车换行。如果是get请求,则没有主体部分,post请求有主体部分。当然里面还有些请求头部比较重要,可以参考[http你不得不知道的那些事(五)-报文头][2]。

    六、服务器处理请求,并对请求做出响应。

浏览器请求报文到达服务器之后,服务器接口会对请求报文进行处理,执行接口对应的代码,处理完成后响应客户端。由于http是无状态的,正常情况下,客户端收到响应后就会直接断开连接,然后一次http事物就完成了。但是http1.0有一个keep-alive的请求字段,可以在一定时间内不断开连接(有时时间甚至很长)。http1.1直接就默认开启了keep-alive选项。这导致了一个后果是服务器已经处理完了请求,但是客户端不会主动断开连接,这就导致服务器资源一直被占用。这时服务器就不得不自己主动断开连接,而主动断开连接的一方会出现TIME_WAIT,占用连接池,这就是产生SYN Flood攻击的原因。

此时有三种处理方式,第一是客户端主动断开连接,第二是服务器主动断开连接,第三是对tcp连接经行设置。第一种情况,如果服务器返回的数据都有确定的content-length属性,或者客户端知道服务器返回的内容终止,则客户端主动断开连接。 第二种情况,服务器可以通过设置一个最大超市时间,可以主动断开tcp连接。第三种情况,调整t三个tcp参数,第一个是:tcp_synack_retries 可以用他来减少重试次数;第二个是:tcp_max_syn_backlog,可以增大syn连接数;第三个是:tcp_abort_on_overflow 处理不过来干脆就直接拒绝连接了。

    七、浏览器收到服务器响应,得到html代码。

其实你心里有疑问,这一步有什么好说的。其实这里面有很多需要注意的点。浏览器发出请求时,请求报文如下:

你需要关注一个报文头--accept。accept代表发送端(客户端)希望接受的数据类型,这是浏览器自动封装的请求头。如果服务器返回的content-type是accept中的任何一个,浏览器都能解析,并直接展示在网页上。如果服务器返回的content-type是其他类型,此时浏览器有三种处理状态:

1、正常显示。例如返回类型为text/javascript,浏览器能直接处理并展示。

2、下载。例如返回类型为application/octet-stream(二进制流,不知道下载文件类型),这种浏览器不能直接处理的,会被下载。

3、报错。当我们返回一个字符串hello world,却使用text/xml,格式时,浏览器不能正确解析,就会报错,并把报错信息呈现在网页中。

浏览器能直接处理很多种格式,并直接呈现在网页中,并不限于accept中规定的字段,具体有哪些,就需要自己亲自动手试试了。

附上一张content-type常用对照表地址:[http content-type常用对照表][4]

    八、渲染页面。

获取到服务器相应之后,浏览器会根据相应的content-type字段对响应字符串进行解析。能够解析并成功解析就显示,能够解析但解析错误就报错,不能解析就下载。由于浏览器采用至上而下的方式解析,所以会先解析html,直到遇到外部样式和外部脚本。这时会阻塞浏览器的解析,外部样式和外部脚本(在没有async、defer属性下)会并行加载,但是外部样式会阻塞外部脚本的执行,dom加载完毕,js脚本执行成功后dom树构建完成(DOMContentLoaded),之后就加载dom中引用的图片等静态资源。(参考文章地址http你不得不知道的那些事(五)-报文头

即:html解析->外部样式、脚本加载->外部样式执行->外部脚本执行->html继续解析->dom树构建完成->加载图片->页面加载完成。

  情况一:如果是动态脚本(即内联脚本)则不受样式影响,在解析到它时会执行。

  情况二:外部样式后续外部脚本含有async属性(IE下为defer),外部样式不会阻塞该脚本的加载与执行

  在外部样式执行完毕后,css附着于DOM,创建了一个渲染树(渲染树是一些被渲染对象的集)。每个渲染对象都包含了与之对应的计算过样式的DOM对象,对于每个渲染元素来说,位置都经过计算,所以这里被叫做“布局”。然后将“布局”显示在浏览器窗口,称之为“绘制”。

  接着脚本的执行完毕后,DOM树构建完成。这时,可以触发DOMContentLoaded事件。DOMContentLoaded事件的触发条件是:在所有的DOM全部加载完毕并且JS加载执行后触发。

 情况一:如果脚本是动态加载,则不会影响DOMContentLoaded时间的触发,浏览器会等css加载完成后再加载图片,因为不确定图片的样式会如何。 

  要点一:CSS样式表会阻塞图片的加载,如果想让图片尽快加载,就不要给图片使用样式,比如宽高采用标签属性即可。

  要点二:脚本不会阻塞图片的加载

  最后页面加载完成,页面load。
 

这就是在浏览器地址栏输入地址到页面渲染完成的全过程,整个过程比较复杂,涉及到很多东西。

 

总结一下:运维人员需要处理页面缓存、cdn及keep-alive引起的连接池占用等问题;后端人员需要处理代码逻辑、缓存、传输优化、报错等问题;前段人员需要做好前端性能优化和配合运维、后端做好借口调试,缓存处理等问题。所以无论是前端、后台、运维都应该很清楚整个流程中的每一步,才能在配合时,得心应手,才能在出现问题时,快速准确的定位问题解决问题,才能在需要优化时,迅速完整的给出方案。本篇文章到这里就结束了,如果你发现什么地方有误或不完善,请在评论区留言,thx~。

ps:本篇文章之介绍了http事物,如果是https事物,整个流程和http事物大致相同,唯一不同的就是在http层和tcp层多了一个ssl层,所以在发送数据前会有个ssl握手,发送数据时会有个ssl层的加密。ssl涉及到的东西也不少,例如ssl握手,加密技术,还要ssl层到底在tcp/ip四层协议哪一层的问题等等。我这里只是粗略说说,如果有比较多感兴趣的同学,我可以另外单开一篇,这篇就到这里了。
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值