从输入 URL 到打开页面发生了什么?
参考文章:https://www.cnblogs.com/liyuanhong/articles/7353974.html
首先从浏览器的地址栏值输入URL地址,如果有历史记录则会自动补全URL地址。
然后根据输入的URL地址类型进行判断,首先如果是本机地址直接定位本机的资源。
其他情况(访问的是网络的资源)下主要发生了两部分的内容:
第一部分是网络通信
第一步:域名到IP地址的解析(对输入的URL的地址进行域名解析)
1.访问浏览器的缓存(查看浏览器的缓存中是否有域名对应的IP地址规则)
2.查询操作系统的hosts文件(查看本地硬盘的hosts文件中是否有域名对应的IP地址规则)
3.查询路由器缓存(查看本地路由器上是否有域名对应的IP地址规则)
4.向本地DNS服务器发送域名解析请求(递归查询)
5.本地DNS服务器代替用户向13根DNS服务器发起迭代查询。(根域名->顶级域->二级域名->子域->主机名)
情况:前三步有任何一步查询成功即返回IP地址,不再进行DNS查询,直接进入下一步,如果域名解析失败,包括DNS查询失败,浏览器则返回 “无法访问此网站 找不到 www.xxx.com 的服务器 IP 地址。”
第二步:传输数据-从客户端应用层到服务端应用层(浏览器向服务器发起HTTP请求)
1.应用层:客户端通过HTTP协议发送HTTP请求报文包含请求报头和请求主体,发送的目标主机就是刚才解析出的IP地址。
2.传输层:TCP协议为传输报文提供可靠的字节流服务,为方便传输将数据分割成多个报文段,TCP通过三次握手请求建立连接后才发送数据。
3.网络层:IP协议将TCP报文段加头封装发送,IP地址通过ARP协议转MAC地址
4.链路层:将IP报文加头封装在链路层传输
5.服务器应用层:将下层传输的按序号到达的数据包层层拆包得到的数据并组装,收到了客户端的HTTP的请求报文
第三步:服务器发送HTTP响应报文
1.web服务器上的web服务处理HTTP请求,例如 Apache,Tomcat,Node.js 等,服务器有时也会为了做负载均衡使用反向代理,利用代理服务器把不同的请求分配到不同的服务器去处理。
2.处理的结果生成HTTP响应报文发送给客户端。
第四步:客户端收到HTTP响应报文根据不同的状态码进行响应结果
1. 200状态码,请求成功,浏览器开始加载HTML文档,同时设置缓存并关闭TCP连接(在HTTP1.1协议下)
2. 301/302 重定向,浏览器跳转到一个新的地址
3. 304 服务器文件未发生改变可以使用缓存资源
4. 400客户端错误:400请求语法有误,服务器无法理解。401认证失败、403客户端权限不够、404 返回失败,页面资源不存在、405请求的方法与后台所规定的方法不符合(get、post)
5. 500 服务器错误:500服务器内部错误,502网关错误(网关或者代理服务器发生错误),503服务器正在停机维护。
第二部分是浏览器的页面渲染(返回200成功后获取响应体的HTML文档内容开始解析)
1.根据HTML文档的内容构建 DOM 树
(1)一些节点是完全不可见的(比如 script标签,meta标签等),这些节点会被忽略,因为他们不会影响渲染的输出
(2) 记住“visibility:hidden”和“display:none”之间的不同,“visibility:hidden”将元素设置为不可见,但是同样在布局上占领一定空间(例如,它会被渲染成为空盒子),但是“display:none”的元素是将节点从整个render tree中移除,所以不是布局中的一部分 。
2.构建 DOM 树的同时也在构造着另一棵树 Render Tree(解析CSS样式成CSSOM,为DOM树匹配CSS规则共同构成 render tree)
3.布局render树 reflow 几何大小和位置发生改变 (浏览器回流发生的位置)
4.绘制render树 repaint 文字、边框、背景颜色、外观风格(重绘发生的位置)
5.js是单线程的,会先执行脚本的同步任务,同步任务执行完后才会执行异步请求,例如Ajax请求,图片音频视频等外部资源。