We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
比较考验理念知识积累,后续笔者会随着经验增加再依次补充。
首先第一步,如果URL是File://协议开头,浏览器首先会查找机子上的本地文件。如果是FTP就会按照其对应规则建立连接。如果是http/https则会按照下面步骤进行。
File://
FTP
http/https
如果地址是直接使用ip时,则跳过域名解析阶段。
地址是使用域名型的,就会进行此步骤,涉及到的概念:
整个查找解析是一个递归过程:首先从
1 客户端/浏览器缓存中查找 -> 2 本地的hosts文件查找 -> 3 本地DNS解析器(此时可能命中缓存) -> 4 本地DNS服务器 ->
当上述这个过程都未命中时,根据本地DNS服务器设置的转发器进行查询。若未用转发模式,则迭代查找过程如下:
5 根域名服务器 -> 6 顶级域名服务器 -> 7 权威域名服务器
缓存与优化
如果是http(s)的链接,还是基于tcp的,需要建立起链接。涉及到TCP的三次握手,主要作用是为了确认双方的接收能力和发送能力是否都正确,指定自己的初始化序列号为后面的可靠性传送做准备。
涉及概念:
一开始:客户端处于Closed状态,服务端处于Listen状态。
Closed
Listen
发起方A向B发起连接请求报文段,tcp首部的控制位SYN设为1,序号seq=x(某个开始的传输字节数)。此时SYN=1时不携带数据,但要消耗一个序号位。此时发起方进入SYN-SENT(同步已发送)阶段。
接收方B收到请求连接报文,若同意建立连接,则发送报文段:设控制位ACK=1,SYN继续为1,确认序号ack设为x+1,同时为自己的序号位seq=y。此时该报文依然不携带数据,TCP的服务器进程进入SYN-RCVN(同步收到状态)。
发送方A接收到确认报文后,还要再发送一次确认:控制位ACK=1,序号seq仍然为x+1,确认号ack为y+1。A发送后进入ESTABLISHED(已建立连接)状态,B收到确认后也进入ESTABLISH状态。
PS:如果不携带数据就不消耗序号位,即上次序号位为a且不带数据,下一次仍可继续发送序号位为a的报文。
延伸:为什么需要第三次握手,而不是两次握手?
因为是为了防止A第一次握手时发送的报文,被某些因素导致延误了,而此时A因为超时,重新建立了连接,当延误的报文到了之后,B继续确认进行第二次握手,重复建立链接。
有了第三次握手,则会确保第一次延误时不会进行多次重复的连接。
TLS以SSL3.0为基准,后又制定了TLS1.0、TLS1.1和TLS1.2。当前主流的版本是SSL3.0和TLS1.0。
整个握手过程采用非对称加密与对称加密混合的方式。因为全部使用非对称加密的方式,算法实现会很耗时间,整个传输过程就会变得效率低。全部采用对称加密的方式,一开始若密钥被监听到,则就不安全。
所以正常数据传输时采用对称加密,而对称加密的密钥,采用安全性更好的非对称加密进行传输。
客户端首先要告诉服务端,自己可以支持哪些加密算法。于是客户端把本地支持的加密套件(cipher suites),以及产生一个随机数(Client Random),两者一并传输给服务端。而且,客户端也要保存这个随机数。
服务端收到信息后,保存第一次的随机数。然后把证书(包含公钥、数字签名、过期信息、其余网站信息),以及生成并保存第二个随机数(Server Random),并确定使用的加密方法,三个信息一并传输回给客户端(server hello done)。
若此次发送的证书信息不齐全时,中间还会发送一个Server Key Exchange信息,补充回给客户端。
Server Key Exchange
接着,客户端收到证书及信息后。首先验证证书的完整性、正确性、以及证书上的域名与服务端域名是否一致。
拓展数字签名:证书的数字签名由CA相关组织私钥加密而成,而浏览器一般内置了知名的机构的信息与公钥,使用机构提供的公钥解密签名:得到哈希摘要算法,以及一段摘要。接着再对证书上的服务端公钥进行哈希摘要并验证。确保中间过程的服务端公钥没被篡改。
验证完证书的正确性后,客户端会使用一些加密算法(例如:RSA, Diffie-Hellman)产生一个48个字节的Key,这个Key叫PreMaster Secret。该Key将会连同前两个随机数,使用共同协商的加密套件,加密生成“对话密钥(Master Key / Session Key)”。
但客户端只用接收到的公钥加密PreMaster Key,把该加密结果发送给服务端。
此处握手可拓展DH算法生成PreMaster Key,那么就不再需要传递Key,只传递需要的参数即可生成。
服务端收到信息后,使用自己的私钥解密,获得PreMaster Key,同样的,因为服务端也有存之前的两个随机数,所以此处也可以根据约定的加密套件生成同样的Master Key。
为了验证之前搭建的加密通道是否成功,服务端会用该Master Key加密一段Finish信息给客户端。如果客户端能对Finish信息进行正常加解密且消息正确的被验证,则说明加密通道已经建立成功,可以正常传输数据。
参考资料: http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html https://blog.csdn.net/u010285974/article/details/85320788
此处权作通过HTTP请求,浏览器已得到HTML数据:
对HTML文本词法分析和语法分析,自上而下加载,遇到<script src="">和<style href="">此类标签,若资源指向外链,则会额外发起请求加载。
<script src="">
<style href="">
script标签:若指明defer,则是并行加载,但会延迟到整个页面解析完再执行。async也是会并行加载,加载完后再执行脚本。
渲染进程将标签内容转换为DOM树
渲染引擎将CSS样式表转化为浏览器可以理解的styleSheets,计算出DOM节点的样式。
styleSheets
首先进行属性值标准化,例如:将color: blue转化为color: rgb(0,0,255) 其次处理样式的继承与层叠 => 从右往左开始匹配
color: blue
color: rgb(0,0,255)
创建renderTree布局树,计算元素的布局信息。
renderTree
结合dom tree和样式规则,生成一颗只包含可见元素的tree。即display: none的tree并不会出现在此模型上。
对布局树进行分层,并生成分层树。
此处考虑到页面中有很多复杂的效果,如一些复杂的 3D 变换、页面滚动,或者使用 z-index 做 z 轴排序等,为了更加方便地实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树(LayerTree)
为每个图层生成绘制列表,并将其提交到合成线程。合成线程将图层分图块,并栅格化将图块转换成位图。
栅格化可以理解为按照图层整合出顶层视角上的显示图块。合成线程优先考虑合成视口及其附近的位图。
合成线程发送绘制图块命令给浏览器进程。浏览器进程根据指令生成页面,并显示到显示器上。
参考:https://mp.weixin.qq.com/s/nMlZWZO6foRUPFK34ouPhg
The text was updated successfully, but these errors were encountered:
No branches or pull requests
分析协议
首先第一步,如果URL是
File://
协议开头,浏览器首先会查找机子上的本地文件。如果是FTP
就会按照其对应规则建立连接。如果是http/https
则会按照下面步骤进行。域名查找解析
如果地址是直接使用ip时,则跳过域名解析阶段。
地址是使用域名型的,就会进行此步骤,涉及到的概念:
整个查找解析是一个递归过程:首先从
1 客户端/浏览器缓存中查找 ->
2 本地的hosts文件查找 ->
3 本地DNS解析器(此时可能命中缓存) ->
4 本地DNS服务器 ->
当上述这个过程都未命中时,根据本地DNS服务器设置的转发器进行查询。若未用转发模式,则迭代查找过程如下:
5 根域名服务器 ->
6 顶级域名服务器 ->
7 权威域名服务器
缓存与优化
建立tcp链接
如果是http(s)的链接,还是基于tcp的,需要建立起链接。涉及到TCP的三次握手,主要作用是为了确认双方的接收能力和发送能力是否都正确,指定自己的初始化序列号为后面的可靠性传送做准备。
涉及概念:
一开始:客户端处于
Closed
状态,服务端处于Listen
状态。第一次握手
发起方A向B发起连接请求报文段,tcp首部的控制位SYN设为1,序号seq=x(某个开始的传输字节数)。此时SYN=1时不携带数据,但要消耗一个序号位。此时发起方进入SYN-SENT(同步已发送)阶段。
第二次握手
接收方B收到请求连接报文,若同意建立连接,则发送报文段:设控制位ACK=1,SYN继续为1,确认序号ack设为x+1,同时为自己的序号位seq=y。此时该报文依然不携带数据,TCP的服务器进程进入SYN-RCVN(同步收到状态)。
第三次握手
发送方A接收到确认报文后,还要再发送一次确认:控制位ACK=1,序号seq仍然为x+1,确认号ack为y+1。A发送后进入ESTABLISHED(已建立连接)状态,B收到确认后也进入ESTABLISH状态。
延伸:为什么需要第三次握手,而不是两次握手?
因为是为了防止A第一次握手时发送的报文,被某些因素导致延误了,而此时A因为超时,重新建立了连接,当延误的报文到了之后,B继续确认进行第二次握手,重复建立链接。
有了第三次握手,则会确保第一次延误时不会进行多次重复的连接。
TSL/SSL握手过程(若有)
TLS以SSL3.0为基准,后又制定了TLS1.0、TLS1.1和TLS1.2。当前主流的版本是SSL3.0和TLS1.0。
整个握手过程采用非对称加密与对称加密混合的方式。因为全部使用非对称加密的方式,算法实现会很耗时间,整个传输过程就会变得效率低。全部采用对称加密的方式,一开始若密钥被监听到,则就不安全。
所以正常数据传输时采用对称加密,而对称加密的密钥,采用安全性更好的非对称加密进行传输。
第一次握手 - Client Hello
客户端首先要告诉服务端,自己可以支持哪些加密算法。于是客户端把本地支持的加密套件(cipher suites),以及产生一个随机数(Client Random),两者一并传输给服务端。而且,客户端也要保存这个随机数。
第二次握手 - Server Hello
服务端收到信息后,保存第一次的随机数。然后把证书(包含公钥、数字签名、过期信息、其余网站信息),以及生成并保存第二个随机数(Server Random),并确定使用的加密方法,三个信息一并传输回给客户端(server hello done)。
第三次 - Client Key Exchange
接着,客户端收到证书及信息后。首先验证证书的完整性、正确性、以及证书上的域名与服务端域名是否一致。
验证完证书的正确性后,客户端会使用一些加密算法(例如:RSA, Diffie-Hellman)产生一个48个字节的Key,这个Key叫PreMaster Secret。该Key将会连同前两个随机数,使用共同协商的加密套件,加密生成“对话密钥(Master Key / Session Key)”。
但客户端只用接收到的公钥加密PreMaster Key,把该加密结果发送给服务端。
第四次 - Server Finish
服务端收到信息后,使用自己的私钥解密,获得PreMaster Key,同样的,因为服务端也有存之前的两个随机数,所以此处也可以根据约定的加密套件生成同样的Master Key。
为了验证之前搭建的加密通道是否成功,服务端会用该Master Key加密一段Finish信息给客户端。如果客户端能对Finish信息进行正常加解密且消息正确的被验证,则说明加密通道已经建立成功,可以正常传输数据。
浏览器渲染
此处权作通过HTTP请求,浏览器已得到HTML数据:
对HTML文本词法分析和语法分析,自上而下加载,遇到
<script src="">
和<style href="">
此类标签,若资源指向外链,则会额外发起请求加载。渲染进程将标签内容转换为DOM树
渲染引擎将CSS样式表转化为浏览器可以理解的
styleSheets
,计算出DOM节点的样式。创建
renderTree
布局树,计算元素的布局信息。对布局树进行分层,并生成分层树。
为每个图层生成绘制列表,并将其提交到合成线程。合成线程将图层分图块,并栅格化将图块转换成位图。
合成线程发送绘制图块命令给浏览器进程。浏览器进程根据指令生成页面,并显示到显示器上。
参考:https://mp.weixin.qq.com/s/nMlZWZO6foRUPFK34ouPhg
The text was updated successfully, but these errors were encountered: