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? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # 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: