浏览器输入网址返回网页过程
1. 在浏览器地址栏中输入URL
当我们在浏览器输入非IP的网址时(如图www.baidu.com【180.101.49.11】),其实这些网站名都是简化后的地址 ,而浏览器只认识IP地址。
2. DNS域名解析,获得域名相对应的IP地址
所以当输入域名地址的时候,浏览器首先会从浏览器缓存中是否存在相应的域名-IP对应关系,如果有则向这个IP地址发送请求,如果没有则继续向系统缓存–>路由缓存中查找,如果都没有,再去DNS服务器中找IP。
DNS解析具体步骤:
- 浏览器缓存:浏览器会记录DNS一段时间,因此,只是第一个地方解析DNS请求;
- 操作系统缓存:如果在浏览器缓存中不包含这个记录,则会使用系统调用操作系统,获取操作系统的记录(保证最近的DNS查询缓存);
- 路由器缓存:如果上述两个步骤均不能成功DNS记录,继续搜索路由器缓存;
- ISP缓存:若上述均失败,继续向ISP搜索。
3. 浏览器向服务器发起TCP连接,与浏览器建立TCP三次握手
三次握手的过程, 假设主机A为客户端,主机B为服务器,
- 第一次握手:刚开始客户端处于 CLOSED 的状态,服务端处于 LISTEN 状态。客户端给服务端发送一个同步序列编号 SYN(Synchronize Sequence Numbers)报文,并指明客户端的初始化序列号 ISN(Initial Sequence Number),此时客户端处于 SYN_SEND 状态。
- 第二次握手:当服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且也指定了自己的初始化序列号 ISN。同时会把客户端的 ISN + 1 作为确认字符 ACK(Acknowledge character)的值,表示自己已经收到了客户端的 SYN,此时服务器处于 SYN_RECV 的状态。
- 第三次握手:当客户端收到 SYN 报文之后,会发送一个 ACK 报文,当然,也同样把服务器的 ISN + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于 ESTABLISHED 状态。服务器收到 ACK 报文之后,也处于 ESTABLISHED 状态,此时,双方成功建立起了连接。
5. 浏览器向服务器发送HTTP请求,请求数据包
与服务器建立了连接后,就可以向服务器发起请求了。发送HTTP请求的过程就是构建HTTP请求报文,并通过TCP协议发送到服务器指定端口(HTTP协议80/8080,HTTPS协议443)。HTTP请求是由三部分组成:请求行、请求报头和请求正文。
6. 服务器处理收到的请求
服务器端收到请求后,由web服务器处理请求,诸如Apache、Ngnix、IIS等。web服务器解析用户请求,确认要调度哪些资源,再通过相应资源的用户请求和参数调用数据库信息 ,将结果通过web服务器返回浏览器客户端。
7. 返回相应结果至浏览器
HTTP响应报文也是由三部分组成:状态码、响应报头和响应报文。
状态码由三位数组成,第一个数字定义了响应的类别,共有5种可能值:
· 1XX:指示信息,表示请求已接受,继续处理。 · 2XX:成功,表示请求已被成功接收、理解、接受。
· 3XX:重定向,要完成请求必须进行更进一步的操作。
· 4XX:客户端错误,请求中有语法错误或无法实现。
· 5XX:服务器端错误,服务器未能实现合法的请求。
常见状态码有:200,204,301,302,304,400,401,404,500
8. 断开TCP连接,TCP四次挥手
为了避免服务器与客户端双方的资源占用和损耗,当双方没有请求或响应传递时,任意一方都可以发起关闭请求。
当客户端和服务端断开连接时要发送四次数据,这个过程称之为四次挥手:
- 第一次挥手:在挥手之前服务端与客户端都处于 ESTABLISHED 状态。客户端发送一个 FIN (Finish) 报文,用来关闭客户端到服务器的数据传输,此时客户端处于 FIN_WAIT_1 状态。
- 第二次挥手:当服务端收到 FIN 之后,会发送 ACK 报文,并且把客户端的序列号值加 1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。
- 第三次挥手:如果服务端同意关闭连接,则会向客户端发送一个 FIN 报文,并且指定一个序列号,此时服务端处于 LAST_ACK 的状态。
- 第四次挥手:当客户端收到 ACK 之后,处于 FIN_WAIT_2 状态。待收到 FIN 报文时发送一个 ACK 报文作为应答,并且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。等待一段时间后会进入 CLOSED 状态,当服务端收到 ACK 报文之后,也会变为 CLOSED 状态,此时连接正式关闭。
9. 浏览器解析渲染页面
浏览器在收到HTML、CSS、JS文件后,就需要进行渲染。
浏览器是一个边解析边渲染的过程。
- 首先浏览器解析HTML文件构建DOM树,然后解析CSS文件构建渲染树,等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上。
这个过程比较复杂,涉及到两个概念:reflow(回流)和repain(重绘)。
DOM节点中的各个元素是以盒模型的形式存在,这些都需要浏览器去计算其位置和大小等,这个过程称为reflow;
当盒模型的位置、大小以及其他属性,如颜色、字体等确定下来之后,浏览器便开始绘制内容,这个过程称为repain。
页面在首次加载时必然会经历reflow和repain。
reflow和repain过程是非常消耗性能的,尤其是在移动设备上,它破坏用户体验,有时会造成页面卡顿。所以我们应该尽可能的减少reflow和repain。- JS的解析是由浏览器中的JS解析引擎完成的。
浏览器在解析过程中,如果遇到请求外部资源时,如图像、JS等。浏览器将重复1-6过程下载该资源。请求过程是异步的,并不会影响HTML文档进行加载,但是当文档加载过程中遇到JS文件,HTML文档会挂起渲染过程,不仅要等到文档中JS文件加载完毕还要等待解析执行完毕,才会继续HTML的渲染过程。原因是因为JS有可能修改DOM结构,这就意味着JS执行完成前,后续所有资源的下载是没有必要的,这就是JS阻塞后续资源下载的根本原因。
CSS文件的加载不影响JS文件的加载,但是却会影响JS文件的执行。
JS代码执行前浏览器必须保证CSS文件已经下载并加载完毕。