浏览器的本地存储
Cookie
Cookie 本质上就是浏览器里面存储的一个很小的文本文件,内部以键值对的方式来存储
(在chrome开发者面板的Application
这一栏可以看到)
向同一个域名下发送请求,都会携带相同的 Cookie,服务器拿到 Cookie 进行解析,便能拿到客户端的状态。
Cookie 的作用很好理解,就是用来做状态存储的,但它也是有诸多致命的缺陷的:
- 容量缺陷,Cookie 的体积上限只有4KB,只能用来存储少量的信息
- 性能缺陷,Cookie 紧跟域名,不管域名下面的某一个地址需不需要这个 Cookie,请求都会携带上完整的 Cookie,这样随着请求数的增多,其实会造成巨大的性能浪费的,因为请求携带了很多不必要的内容。
- 安全缺陷,由于 Cookie 以纯文本的形式在浏览器和服务器中传递,很容易被非法用户截获,然后进行一系列的篡改,在 Cookie 的有效期内重新发送给服务器,这是相当危险的。另外,在HttpOnly为 false 的情况下,Cookie 信息能直接通过 JS 脚本来读取。
localStorage
localStorage
有一点跟Cookie
一样,就是针对一个域名,在同一个域名下,会存储相同的一段localStorage
- localStorage 的容量上限为5M,相比于
Cookie
的4K大大增加。当然这个5M是针对一个域名的,因此对于一个域名是持久存储的。 - 只存在客户端,默认不参与与服务端的通信。这样就很好地避免了 Cookie 带来的性能问题和安全问题。
- 接口封装。通过local Storage暴露在全局,并通过它的
setItem
和getItem
等方法进行操作,非常方便。
sessionStorage
容量上限也为 5M。
只存在客户端,默认不参与与服务端的通信。
接口封装。除了sessionStorage名字有所变化,存储方式、操作方式均和 localStorage 一样。
区别
:sessionStorage:当窗口关闭时数据销毁,localStorage:永久生效,除非手动删除
浏览器的缓存
首先通过 Cache-Control
验证强缓存是否可用
- 如果强缓存可用,直接使用
- 否则进入协商缓存,即发送 HTTP 请求,服务器通过请求头中的
If-Modified-Since
或者If-None-Match
字段检查资源是否更新 - 若资源更新,返回资源和200状态码 , 否则返回304,告诉浏览器直接从缓存获取资源
浏览器的渲染
- 处理 HTML 并构建 DOM 树
- 处理 CSS 构建 CSSOM 树
- 将 DOM 与 CSSOM 合并成一个渲染树
- 根据渲染树来布局,计算每个节点的位置
- 调用 GPU 绘制,合成图层,显示在屏幕上
两个重要的概念,重绘
与回流
:
- 重绘:当节点需要更改外观而不会影响布局的,比如改变 color 就叫称为重绘
- 回流:布局或者几何属性需要改变就称为回流
回流必定会发生重绘,重绘不一定会引发回流, 回流所需的成本比重绘高的多,改变深层次的节点很可能导致父节点的一系列回流
当 Event loop 执行完 Microtasks 后,会判断 document 是否需要更新。因为浏览器是 60Hz 的刷新率,每 16ms 才会更新一次
HTTP解析过程
DNS解析
由于我们输入的是域名,而数据包是通过IP地址
传给对方的。因此我们需要得到域名对应的IP地址
。这个过程需要依赖一个服务系统, 这个系统将域名和 IP 一一映射,我们将这个系统就叫做DNS(域名系统)得到具体 IP 的过程就是DNS解析
建立TCP连接
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议
建立
TCP连接
经历了下面三个阶段:
- 通过三次握手(总共发送3个数据包确认已经建立连接)建立客户端和服务器之间的连接
-
第一次握手:客户端发送一个SYN码给服务器,要求建立数据连接;
-
第二次握手: 服务器SYN和自己处理一个SYN(标志);叫SYN+ACK(确认包);发送给客户端,可以建立连接
-
第三次握手: 客户端再次发送ACK向服务器,服务器验证ACK没有问题,则建立起连接
- 进行数据传输,这里有一个重要的机制,就是接收方接收到数据包后必须要向发送方
确认
, 如果发送方没有接到这个确认
的消息,就判定 为数据包丢失,并重新发送该数据包。当然,发送的过程中还有一个优化策略,就是把大的数据包拆成一个个小包
,依次传输到接收方,接收方按照这个小包的顺序把它们组装
成完整数据包。 - 断开连接的阶段,数据传输完成,现在要断开连接了,通过四次挥手来断开连接。
-
第一次挥手: 客户端发送FIN(结束)报文,通知服务器数据已经传输完毕;
-
第二次挥手: 服务器接收到之后,通知客户端我收到了SYN,发送ACK(确认)给客户端,数据还没有传输完成
-
第三次挥手: 服务器已经传输完毕,再次发送FIN通知客户端,数据已经传输完毕
-
第四次挥手: 客户端再次发送ACK,进入TIME_WAIT状态;服务器和客户端关闭连接;
发送 HTTP 请求
现在TCP连接
建立完毕,浏览器可以和服务器开始通信,开始发送 HTTP 请求。浏览器发 HTTP 请求要携带三样东西:请求行、请求头和请求体
网络响应
HTTP 请求到达服务器,服务器进行对应的处理。最后要把数据传给浏览器,也就是返回网络响应。
跟请求部分类似,网络响应具有三个部分:响应行、响应头和响应体
响应完成之后怎么办? TCP 连接就断开了吗?
不一定。这时候要判断Connection
字段, 如果请求头或响应头中包含Connection: Keep-Alive,表示建立了持久连接,这样TCP
连接会一直保持,之后请求统一站点的资源会复用这个连接,否则断开TCP
连接, 请求- 响应流程结束
浏览器的安全
什么是 XSS 攻击
XSS
是(跨站脚本),XSS 攻击是指浏览器中执行恶意脚本(无论是跨域还是同域),从而拿到用户的信息并进行操作
这些操作一般可以完成下面这些事情:
- 窃取
Cookie
- 监听用户行为,比如输入账号密码后直接发送到黑客服务器。
- 修改 DOM 伪造登录表单。
- 在页面中生成浮窗广告。
XSS 攻击的实现有三种方式——存储型、反射型和文档型
存储型
存储型
,顾名思义就是将恶意脚本存储了起来,其实存储型的 XSS 将脚本存储到了服务端的数据库,然后在客户端执行这些脚本,从而达到攻击的效果
常见的场景:
是留言评论区提交一段脚本代码,如果前后端没有做好转义的工作,那评论内容存到了数据库,在页面渲染过程中直接执行
, 相当于执行一段未知逻辑的 JS 代码,是非常恐怖的。这就是存储型的 XSS 攻击。
反射型
反射型XSS
指的是恶意脚本作为网络请求的一部分
之所以叫它反射型
, 是因为恶意脚本是通过作为网络请求的参数,经过服务器,然后再反射到HTML文档中,执行解析
和存储型不一样的是 , 服务器并不会存储这些恶意脚本
文档型
文档型的 XSS 攻击并不会经过服务端,而是作为中间人
的角色,在数据传输过程劫持到网络数据包,然后修改里面的 html 文档!
防范措施
利用 CSP
CSP,即浏览器中的内容安全策略,它的核心思想就是服务器决定浏览器加载哪些资源,具体来说可以完成以下功能:
- 限制其他域下的资源加载。
- 禁止向其它域提交数据。
- 提供上报机制,能帮助我们及时发现 XSS 攻击。
利用 HttpOnly
很多 XSS 攻击脚本都是用来窃取Cookie, 而设置 Cookie 的 HttpOnly 属性后,JavaScript 便无法读取 Cookie 的值。这样也能很好的防范 XSS 攻击。
总结
一个信念: 不要相信用户的输入,对输入内容转码或者过滤,让其不可执行。
两个利用: 利用 CSP,利用 Cookie 的 HttpOnly 属性。
什么是CSRF攻击
CSRF(Cross-site request forgery), 即跨站请求伪造,指的是黑客诱导用户点击链接,打开黑客的网站,然后黑客利用用户目前的登录状态发起跨站请求。
CSRF
攻击的原理。和XSS
攻击对比,CSRF 攻击并不需要将恶意代码注入用户当前页面的HTML
文档中,而是跳转到新的页面,利用服务器的验证漏洞和用户之前的登录状态来模拟用户进行操作
防范措施
- 利用Cookie的SameSite属性
SameSite
可以设置为三个值,Strict
、Lax
和None
-
Strict
模式下,浏览器完全禁止第三方请求携带Cookie。比如请求sanyuan.com网站只能在sanyuan.com域名当中请求才能携带 Cookie,在其他网站请求都不能。 -
Lax
模式,就宽松一点了,但是只能在 get 方法提交表单况或者a 标签发送 get 请求的情况下可以携带 Cookie,其他情况均不能。 -
None
模式下,也就是默认模式,请求会自动携带上 Cookie。
- 验证来源站点
这就需要要用到请求头中的两个字段: Origin 和 Referer
Origin只包含域名信息,而 Referer 包含了具体的 URL 路径。
当然,这两者都是可以伪造的,通过 Ajax 中自定义请求头即可,安全性略差。
- CSRF Token
首先,浏览器向服务器发送请求时,服务器生成一个字符串,将其植入到返回的页面中。
然后浏览器如果要发送请求,就必须带上这个字符串,然后服务器来验证是否合法,如果不合法则不予响应。这个字符串也就是CSRF Token
,通常第三方站点无法拿到这个 token,因此也就是被服务器给拒绝。
总结
CSRF攻击一般会有三种方式:
- 自动 GET 请求
- 自动 POST 请求
- 诱导点击发送 GET 请求。
- 防范措施: 利用
Cookie
的SameSite
属性、验证来源站点和 CSRF Token
作者:神三元
链接:链接
来源:掘金