1.输入URL地址
在浏览器中输入URL地址时会发现若是曾经输入过的URL地址,浏览器会自动补全 URL的地址信息。
2.浏览器查找域名对应的IP地址。
当用户通过浏览器发送请求式,浏览器就开始解析这个域名了,通过DNS域名系统通过域名找到对应的IP,首先会查找一下本地的host文件中有没有对应的IP,没有的话就发送一个DNS请求到DNS服务器,DNS服务器先查询浏览器的缓存记录,没有的话向上一级DNS根服务器进行查询,依次向上查找,找到后将对应关系放在缓存中,便于用户下一次的查找。
那什么是DNS呢,DNS把IP和域名互相映射,并映射成一个分布式数据库,可以让用户访问互联网,DNS的协议是UDP协议,当请求大于512字节时端口号为53。
3.当拿到域名对应的IP地址以后,浏览器会向服务器发送一个TCP连接请求有TCP请求就会有三次握手协议了。进行三次握手的目的是为了保证客户端与服务端接收能力和发送能力的正常,
第一次握手:客户端向服务端发送一个SYN报文,用于请求建立连接,SYN=1,随机产生一个seq=y的数据包到服务器,注意此时的报文段不能携带数据,客户端处于SYN_SENT状态。通过第一此握手,服务端可以知道客户端的发送能力正常,自己的接收能力正常
发送数据:SYN=1,seq=y;
客户端状态:SYN_SENT状态;
第二次握手:服务端收到报文之后,知道客户端请求建立连接,将标志位SYN和ACK都置为1,把客户端的初始化序列号ISN(此时为y)+1作为ACK的值,此时ack=y+1,并指定自己的初始化序列seq=x,这一阶段服务器处于SYN_RCVD状态,不能携带数据。
通过第二次握手,客户端可以知道服务端的发送能力和接收能力是正常的,自己的接收与发送能力是正常的
发送数据:SYN=1,ACK=1;ack=y+1;seq=x;
服务端的状态:SYN_RCVD状态;
第三次握手:客户端收到报文之后,发送一个ACK报文,ACK=1,同样将服务端的初始化序列号ISN(此时为x)+1作为ACK的值,此时ack=x+1,可以携带数据。
通过第三次握手,服务端可以知道自己的接收和发送能力正常,客户端的接收与发送能力正常。
发送数据:ACK=1,ack=x+1
客户端与服务端的状态都为:ESTABLISHED状态
这样完成了三次握手,建立连接开始传输数据了
4.建立TCP连接之后,就会发起一个HTTP请求
发起请求的时候会有一些一些请求信息,如请求方法,请求头,请求体,这是通过HTTP协议进行一层层的包装。
5.服务器开始处理请求
服务器对HTTP协议进行解析,进一步封装成HTTP Request对象,之后将处理结果返回。返回的结果包括状态行(即状态码等信息),响应头,响应体。
6.浏览器开始解析和渲染页面
浏览器在解析html文件时是自上而下的加载,并在加载的时候进行解析。
(1)浏览器载入HTML文件,按照页面文档的树形目录加载,生成一个DOM树,按顺序加载,doucument.readyState=loading。
(2)在加载过程中,如果发现在head标签中,有一个link标签引用外部CSS文件,浏览器又发出CSS文件的请求,并继续解析文档
(3)浏览器继续载入HTML文件中body部分的代码,服务器返回这个CSS文件,浏览器并行下载该CSS文件(异步处理,创建线程加载),等待CSS文件已经下载完毕了,可以开始渲染页面了。
(4)解析CSS文件生成渲染树,根据生成的DOM树依次进行渲染,在渲染的过程中,如果发现img标签引用图片,就会向服务器发出请求,此时浏览器继续渲染后面的大妈,而不会等待图片的下载。
(6)浏览器在最后发现一个script标签引用的js文件,便进行下载,下载后进行解析,解析过程中阻塞了HTML文件的下载,运行后如果影响了页面的布局,浏览器就要重新渲染这部分代码。如果script标签中有的defer,async时创建线程加载,继续解析文档(与加载图片的情况一致),这相当于js文件立即加载,延迟执行
(7)dom树绘制完成(但可能link,href,img的src等没有下载完成) doucument.readyState=interactive,dom树绘制完成后触发 DOMContentLoaded事件
(8)文档解析完成后(link,href,img的src等全部下载完成) doucument.readyState=loaded||complete。服务器返回下载好的文件,浏览器回过头将那部分代码重新渲染。
7.关闭TCP连接(四次挥手)
- 第一次挥手:客户端发送一个FIN告诉服务端要关闭连接,关闭了客户端到服务端之间的数据传输
- 第二次挥手:服务端收到FIN后,发送一个ACK报文告诉客户端收到了消息,这个报文让客户端知道了服务端已经知道自己想要释放连接的请求
- 第三次挥手:服务端发送FIN,关闭了服务端到客户端之间的数据传输
- 第四次挥手:客户端收到FIN后,确认了服务端已经做好了释放连接的准备,发送一个ACK报文,这个报文让服务端知道客户端已经了解自己准备好释放连接了