一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么?
主要包括以下几个基本步骤:
浏览器的地址栏输入URL并按下回车。
浏览器查找当前URL是否存在缓存,并比较缓存是否过期。
DNS解析URL对应的IP。
根据IP建立TCP连接(三次握手)。
HTTP发起请求。
服务器处理请求,浏览器接收HTTP响应。
渲染页面,构建DOM树。
关闭TCP连接(四次挥手)。
1. DNS域名解析:
域名解析的过程实际是将域名还原为IP地址的过程。
- 浏览器缓存:浏览器会按照一定的频率缓存 DNS 记录。
- 操作系统缓存:如果浏览器缓存中找不到需要的 DNS 记录,那就去操作系统中找。
- 路由缓存:路由器也有 DNS 缓存。
- ISP 的 DNS 服务器:ISP 是互联网服务提供商(Internet Service Provider)的简称,ISP 有专门的 DNS 服务器应对 DNS 查询请求。
- 根服务器:ISP 的 DNS 服务器还找不到的话,它就会向根服务器发出请求,进行递归查询(DNS 服务器先问根域名服务器.com 域名服务器的 IP 地址,然后再问.baidu 域名服务器,依次类推)
-递归查询:如果上述步骤还找不到,则ISP的DNS服务器就会进行递归查询,所谓递归查询就是如果主机所询问的本地域名服务器不知道被查询域名的IP地址,那么本地域名服务器就以DNS客户的身份,向其他根域名服务器继续发送查询请求报文,而不是让该主机自己进行下一步查询。(本地域名服务器地址是通过DHPC协议获取地址,DHPC是负责分配IP地址的)
-迭代查询:本地域名服务器采用迭代查询,他先向一个根域名服务器查询。本地域名服务器向根域名服务器的查询一般都是采用迭代查询。所谓迭代查询就是当根域名服务器收到本地域名服务器发出的查询请求报文后,要么告诉本地服务器下一步查询哪一个域名服务器,然后本地域名服务器进行后续的查询。(而不是替代本地域名服务器进行后续查询)
2. 根据IP建立TCP连接(三次握手)
- 主机浏览器通过DNS解析得到了目标服务器的IP地址后,与服务器建立TCP连接
- TCP三次握手建立连接:浏览器所在的客户机向服务器发出连接请求报文(SYN标志为1);客户机接收到确认报文后,再次向服务器发出报文(SYN,ACK标志位均为1);客户机接收到确认报文后,再次向服务器发出报文,确认已接收到确认包问;此处客户机与服务器之间的TCP连接建立完成,开始通信
完成三次握手,客户端与服务器开始传送数据。
3.浏览器向服务器发送HTTP请求
完整的HTTP请求包含请求起始行、请求头部、请求主体三部分。
与服务器建立了连接后,就可以向服务器发起请求了。这里我们先看下请求报文的结构(如下图):
4.服务器“处理”请求,返回响应结果
服务器端收到请求后的由web服务器(准确说应该是http服务器)处理请求,诸如Apache、Ngnix、IIS等。web服务器解析用户请求,知道了需要调度哪些资源文件,再通过相应的这些资源文件处理用户请求和参数,并调用数据库信息,最后将结果通过web服务器返回给浏览器客户端。
服务器在收到浏览器发送的HTTP请求之后,会将收到的HTTP报文封装成HTTP的Request对象,并通过不同的Web服务器进行处理,处理完的结果以HTTP的Response对象返回,主要包括状态码,响应头,响应报文三个部分。
状态码:
1**:信息性状态码
2**:成功状态码
200:OK 请求正常处理
204:No Content请求处理成功,但没有资源可返回
206:Partial Content对资源的某一部分的请求
3**:重定向状态码
301:Moved Permanently 永久重定向
302:Found 临时性重定向
304:Not Modified 缓存中读取
4**:客户端错误状态码
400:Bad Request 请求报文中存在语法错误
401:Unauthorized需要有通过Http认证的认证信息
403:Forbidden访问被拒绝
404:Not Found无法找到请求资源
5**:服务器错误状态码
500:Internal Server Error 服务器端在执行时发生错误
503:Service Unavailable 服务器处于超负载或者正在进行停机维护
5. 页面渲染
前面有提到http交互,那么接下来就是浏览器获取到html,然后解析,渲染
解析HTML,构建DOM树
解析CSS,生成CSS规则树
合并DOM树和CSS规则,生成render树
布局render树(Layout/reflow),负责各元素尺寸、位置的计算
绘制render树(paint),绘制页面像素信息
浏览器会将各层的信息发送给GPU,GPU会将各层合成(composite),显示在屏幕上
6. 断开连接
当数据传送完毕,需要断开 tcp 连接,此时发起 tcp 四次挥手。
- 浏览器所在的主机向服务器发出连接释放报文,然后停止发送数据
- 服务器接收到释放连接报文后发出确认报文,然后将服务器上未传送完的数据发送完
- 服务器数据传输完毕后,向客户机发送连接释放报文
- 客户机接收到报文后,发出确认,然后等待一段时间后,释放TCP连接
为什么建立连接是三次握手,而断开连接是四次挥手呢?
建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个
报文里发送给客户端。而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了
但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一
些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分
开发送,从而导致多了一次。