本文旨在总结一下前端相关的网络和安全相关的一些知识点,每个点都相对简陋,只用来了解个大概。
1)解析文档构建DOM树
HTML/XHTML/SVG:解析这三种文件后,会生成DOM树(DOM Tree)
CSS:解析样式表,生成CSS规则树(CSS Rule Tree)
JavaScript:解析脚本,通过DOM API和CSSOM API操作DOM Tree和CSS Rule Tree,与用户进行交互。
2)构建渲染树
解析文档完成后,浏览器引擎会将 CSS Rule Tree 附着到DOM Tree 上,并根据DOM Tree 和 CSS Rule Tree构造 Rendering Tree(渲染树)
3)布局与绘制渲染树
解析position, overflow, z-index等等属性,计算每一个渲染树节点的位置和大小,此过程被称为reflow。最后调用操作系统的Native GUI API完成绘制(repain)
解析html文档,遇到HTML标签时,构建DOM树。在构建DOM的过程中,如果遇到外联的样式声明或脚本声明,则暂停文档解析,创建新的网络连接,开始下载样式文件和脚本文件。样式文件下载完成后,构建CSS Rule DOM,脚本文件下载完成后,解释并立即执行。构建DOM的同时,结合CSS规则树完成页面渲染。如果DOM树先于CSS规则树构建完成,则在CSS规则树构建完成后,页面会发生一次重绘,将新构建的CSS规则应用于渲染树。
脚本文件对文档解析的影响在这个过程中,脚本文件的下载和执行是与文档解析同步进行的,脚本文件的下载和执行都会阻塞文档的解析,如果控制得不好,在用户体验上就会造成一定程度的影响。
1).css加载不会阻塞DOM树的解析
2).css加载会阻塞DOM树的渲染
3).css加载会阻塞后面js语句的执行
根据上一点浏览器渲染流程,可以知道,当css树还没构建完成时,页面是不会渲染到浏览器界面的,这也是为什么当css下载过慢时,会出现白屏的现象。因此,为了避免让用户看到长时间的白屏时间,我们应该尽可能的提高css加载速度
1)使用CDN(因为CDN会根据你的网络状况,替你挑选最近的一个具有缓存内容的节点为你提供资源,因此可以减少加载时间)
2)对css进行压缩(可以用很多打包工具,比如webpack,gulp等,也可以通过开启gzip压缩)
3)合理的使用缓存(设置cache-control,expires,以及E-tag都是不错的,不过要注意一个问题,就是文件更新后,你要避免缓存而带来的影响。其中一个解决防范是在文件名字后面加一个版本号)
4)减少http请求数,将多个css文件合并,或者是干脆直接写成内联样式(内联样式的一个缺点就是不能缓存)
5)利用媒体类型和查询来解除对渲染的阻塞。
缓存位置分为:Service Worker;Memory Cache;Disk Cache;Push Cache(推送缓存)是HTTP/2中的内容,当前面三种缓存都没有命中时,它才会被使用
Service Worker 是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。使用 Service Worker的话,传输协议必须为 HTTPS。因为 Service Worker 中涉及到请求拦截,所以必须使用 HTTPS 协议来保障安全。Service Worker 的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的
缓存策略分两种:强缓存、协商缓存。强缓存不会向服务器发送请求,直接从缓存中读取资源,如果命中并有效就使用缓存,否则就发请求,强缓存可以通过设置两种 HTTP Header 实现:Expires 和 Cache-Control;协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识(Etag,If-Modified-Since等)决定是否使用缓存的过程。如果未变会返回304告知浏览器直接使用缓存资源,否则返回最新资源。
缓存方法即其对比:
1)响应头Last-Modified和请求头加If-Modified-Since
弊端:如果本地打开缓存文件,即使没有对文件进行修改,但还是会造成 Last-Modified 被修改,服务端不能命中缓存导致发送相同的资源。因为 Last-Modified 只能以秒计时,如果在不可感知的时间内修改完成文件,那么服务端会认为资源还是命中了,不会返回正确的资源。
2)ETag和If-None-Match
两种方法对比:
Last-Modified的时间单位是秒,如果某个文件在1秒内改变了多次,那么他们的Last-Modified其实并没有体现出来修改,但是Etag每次都会改变确保了精度;如果是负载均衡的服务器,各个服务器生成的Last-Modified也有可能不一致。
第二在性能上,Etag要逊于Last-Modified,毕竟Last-Modified只需要记录时间,而Etag需要服务器通过算法来计算出一个hash值。
第三在优先级上,服务器校验优先考虑Etag
关于缓存推荐阅读这篇文章
2xx表示成功的请求
200表示OK,正常返回信息
204 成功处理,没有内容。
206 范围请求响应
3xx表示重定向
301表示永久重定向,请求的网页已经永久移动到新位置
302表示临时重定向
304表示自从上一次请求以来,页面的内容没有改变过
4xx表示客户端错误
400请求报文存在语法错误
401表示认证失败(发送的请求需要通过HTTP认证)
403表示没有权限,服务器拒绝访问
404表示请求的资源不存在,一般是路径写错了
405表示请求方法不允许,一般是请求方法用错了
5xx表示服务器错误
500表示服务器执行请求时发生错误
503表示服务器暂时无法处理请求(超负载或正在停机维护)
1)查找 disk cache 中是否有匹配,如有直接显示缓存内容
2)DNS域名解析
3)三次握手,建立连接,发送请求
4)服务器收到请求,处理请求,返回响应
5)4次挥手,断开TCP连接
6)浏览器根据返回数据进行页面渲染
三次握手:
目的:为了准确无误地将数据送达目标处,TCP协议采用了三次握手策略。
发送端首先发送一个带SYN标志的数据包给对方。接收端收到后,回传一个带SYN/ACK标志的数据包以示传达确认信息。最后,发送端再回传一个带ACK标志的数据包,代表握手结束,建立连接。
四次挥手:
为了持久连接,其特点是只要任意一端没有明确提出断开连接,则保持TCP连接状态;其好处是在于减少了TCP连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。另外,减少开销的时间,使HTTP请求和响应能更早结束,从而提高web页面的显示速度。
服务器端发送一个带FIN标记的数据包给客户端;客服端分两次发送带ACK、FIN标志数据包给服务端;服务端发送带ACK标志的数据包给客户端并断开连接
http不足之处:
1)通信使用明文,不加密,内容可能被窃听。
2)不验证通信方的身份,因此可能会遭遇伪装。
3)无法证明报文的完整性,所以有可能已遭篡改。
https:
1)用SSL(安全套接层)对通信线路进行加密
2)SSL有一种称为证书的手段,用于确定通信双方。通过使用证书,以证明通信方就是意料中的服务器,客户端持有证书即可完成个人身份的确认。
3)通过校验数字签名,将一段文本先用Hash函数生成消息摘要,然后用发送者的私钥加密生成数字签名,与原文文一起传送给接收者。接收者通过校验数字签名来确定完成性。
https的缺点:
1)https与http相比通信速度会更慢,SSL必须进行加密处理,服务器和客户端在加密解密的过程中会消耗更多的硬件资源导致处理速度变慢。
2)https通信,证书是必不可少的,而证书是需要花钱的。
前端中比较常见的攻击手段:
1)XSS攻击
xss:全称跨站脚本攻击(Cross-Site Scripting),简单的说就是攻击者通过在目标网站上注入恶意脚本并运行,获取用户的敏感信息如 Cookie、SessionID 等,影响网站与用户数据安全。
原因:当攻击者通过某种方式向浏览器页面注入了恶意代码,并且浏览器执行了这些代码。
解决措施:渲染页面前都要先做 HTML 过滤,然后再渲染,对输入数据中的html标签< >进行转义 < > httpOnly
2)CSRF 攻击
CSRF 攻击全称跨站请求伪造(Cross-site Request Forgery),简单的说就是攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF的另一个特征是,攻击者无法直接窃取到用户的信息(Cookie,Header,网站内容等),仅仅是冒用Cookie中的信息。
策略:
CSRF自动防御策略:同源检测(Origin 和 Referer 验证)。
CSRF主动防御措施:Token验证 或者 双重Cookie验证 以及配合Samesite Cookie。
保证页面的幂等性,后端接口不要在GET页面中做用户操作。
推荐《图解HTTP》这本书,通过阅读它,对以上知识点你会有更全面的了解。