整体流程
键入域名比如baidu.com----> 判断缓存是否存在 ----> DNS解析URL中对应的IP ---> 根据IP建立TCP连接(三次握手)---> HTTP发送请求传输数据 ----> 服务器处理请求,返回请求数据 ----> 浏览器渲染页面,构建DOM ----> 构建完成,关闭TCP连接(四次挥手)
分节点简述
URL
URL 代表着是统一资源定位符
scheme://host.domain:port/path/filename
说明:
scheme - 定义因特网服务的类型。最常见的类型是 http
host - 定义域主机(http 的默认主机是 www)
domain - 定义因特网域名,比如 runoob.com
:port - 定义主机上的端口号(http 的默认端口号是 80)
path - 定义服务器上的路径(如果省略,则文档必须位于网站的根目录中)。
filename - 定义文档/资源的名称
补充说明:
- 浏览器的同源跨源策略
同源策略(same-origin policy):限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。
目的:防止CSRF(Cross-Site Request Forgery,跨站请求伪造)。
同一个源:协议,域名,端口都相同.IE例外,IE中只要协议和域名相同,就认为是同一个源
- 跨域
不同源之间交互时,会受同源策略的约束, 属于跨域。
那么如何越过跨域:‘
1、AJAX跨域
JSONP、CORS(服务端在响应头中声明允许的页面header('Access-Control-Allow-Origin:*');)和nginx反向代理
2、数据存储跨域
比如跨域读取localstorage,可采用PostMessage API。
<iframe src="http://localhost:5500/public/1.html" style="display: none;" frameborder="0"></iframe>
<script>
window.onload = function () {
setTimeout(() => {
window.frames[0].postMessage("test", "http://localhost:5500")
}, 3000);
}
window.addEventListener('message', function(ev){
console.log(ev);
localStorage.setItem('test', ev.data)
})
</script>
比如cookie跨域,是采用子父域名声明。比如一个页面可以为本域和任何父域设置Cookie,浏览器允许任何子域来访问父域的cookie。比如aa.xx.com可以为aa.xx.com和xx.com设置Cookie,nn.aa.xx.com可以为nn.aa.xx.com、aa.xx.com和xx.com设置Cookie
TCP
TCP三次握手
第一次握手,客户端发生SYN包(SYN=1 seq=x)到服务器,进入SYN_SEND状态,等待服务器确认。
第二次握手,服务端收到SYN包后,确认客户端的SYN(ACK=x+1)表示同意连接,同时也发送自己的一个SYN包(seq=y),即SYN+ACK(SYN=1 seq=y ACK=x+1), 此时服务器进入SYN_RECV状态。
第三次握手,客户端收到服务器的SYN+ACK包,向服务器发送确认ACK包(ACK=y+1), 即(seq=x+1, ACK=y+1),然后进入ESTABLISHED(TCP连接成功),等待传输数据。
为什么必须三次握手,不是两次握手。为了防止已失效的连接请求再次发送到服务端,因而产生错误
。如果客户端发送第一次连接请求到服务器,但是由于网络延迟等原因,没有收到确认。然后客户端再次发送请求到服务端连接确认。过了一段时间后,第一次的连接请求到达了服务器,此时服务器误认为客户端又发了一次连接请求,继而进行了确认,但是此时客户端不理睬服务器的确认,服务器一直等待客户端发送数据,造成了资源的浪费。
TCP四次挥手
第一次挥手,客户端发送FIN(FIN=1 seq=x)请求服务器断开连接,表示已无数据发送,客户端进入FIN-WAIT1状态。
第二次挥手,服务器发送ACK同意关闭(ACK=1 seq=y ack=x+1)。服务器进入close-waite状态。
第三次挥手,服务器完成所有的数据传送后,再次发送ACK确认关闭(FIN=1 ACK=1 ack=x+1 seq=z ),此时服务器进入LAST-ACK最终确认状态。
第四次挥手,确认双发数据全部传输完成后,客户端发送ACK确认(ACK=1 ack=z+1 seq=x+1)
为什么中间服务器两次等待确认,一是为了保证客户端的最后一个请求包能够到达服务器,二是为了保证因网络原因等已失效的请求报文出现在本连接中。总而言之一句话,需要保证所有的数据传输完成。
浏览器渲染
浏览器的简单的渲染流程如下:
- 解析html构建DOM树 ----> 解析css构建CSS树:此时html和css被解析成树形的数据结构
- 构建Render树:将DOM树和CSS树结合形成的Render树
- 布局Render树:有了Render树,浏览器已经知道那些有哪些节点,各个节点的css定义和以及它们的从属关系,从而计算出每个节点在屏幕中的位置,经过Layout计算可见节点在设备视口(viewport)内的几何信息
- 绘制render树:按照已知Render树和布局的几何信息,通过GPU把内容画在屏幕上
这是大概的渲染流程。