手记

<计算机与网络篇> 应用层缓存机制

上篇我们讲到浏览器缓存策略中的 HTTP 缓存机制,接下来我们继续浅谈一下浏览器应用层面中的缓存机制,跟上篇一样先看看应用层缓存的类别有哪些?

进入 Chrome 的开发者模式选择 Application 页签,可以看到下图( Background Services 为新版 Chrome 才会有

我们来一项项的说明:

栏目 项目 描述
Application Manifest Manifest ( Web应用程序清单 ) 在一个JSON文本文件中提供有关应用程序的信息(如名称,作者,图标和描述)。Manifest 的目的是将Web应用程序安装到设备的主屏幕,为用户提供更快的访问和更丰富的体验。
- Service Workers Service Workers 是一个 web API,是 Web Workers 的一种实现,功能是可以拦截、处理请求,配合 CacheStorage 等 API,可以做到将资源存储到本地等,实现离线访问。(也就是我们上篇所提及的 HTTP 缓存位置的其中一项)
- Clear storage 清理浏览器缓存工具。
Storage(缓存) Local Storage 用于长久保存整个网站的数据(键值对存储方式),保存的数据没有过期时间,直到手动去删除。也就是我们常用的localStorage.setItemgetItem()removeItem()clear(),的存储位置。
- Session Storage 用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。API与local一样,只是生命周期不同,存储数据大小两个都是5MB。
- indexedDB 浏览器提供的本地数据库,它可以被网页脚本创建和操作。IndexedDB 允许储存大量数据,提供查找接口,还能建立索引。IndexedDB 不属于关系型数据库(不支持 SQL 查询语句),更接近 NoSQL 数据库。
- Web SQL Web SQL 数据库 API 并不是 HTML5 规范的一部分,但是它是一个独立的规范,引入了一组使用 SQL 操作客户端数据库的 API。
- Cookies 指某些网站为了辨别用户身份、进行 session (存储在服务端的用户信息)跟踪而储存在用户本地终端上的数据(通常经过加密),一般大小只有4k,会赋在每次的请求头中。
Cache(贮存物) Cache storage CacheStorage 接口表示 Cache 对象的存储。为 Service Workers 与其他 Worker 服务
- Application storage 是 HTML5 新增的一个离线应用功能,在对应用进行缓存的时候需要一个 manifest 文件。
Background Services (后台服务) Background Fetch 用于生成在后台挂起的 fetch 资源任务
- Background Sync 生成在后台挂起执行的同步任务
Frames(构架) top 用于显示当前页面所有的资源列表,包括字体、图片、js源码等

大体上我们可以把他们分成两类,一种是实现跟踪浏览器用户身份功能的 CookiesSession, 以及为了解决 Cookies 弊端在 HTML5 时代所发展出来的 Web Storage。另一种是针对 PWAProgressive Web App)即渐进式 web 应用服务,是为了下一代 web APP 服务的缓存机制。


Cookies

随着 Web 的蓬勃发展,在业务上出现用户身份的概念,比如在论坛这一应用场景中。Cookies 的出现,提供了存储用户信息的功能,免除了客户从一个页面跳转至另一个页面时重新输入认证信息。

Cookies 作为最古老且很成熟的 HTTP 状态保持办法又有哪些特点呢?

1. Cookies 的组成

Cookie 是一段不超过4KB的小型文本数据,由一个名称(Name)、一个值(Value)和其它几个用于控制 Cookie 有效期、安全性、使用范围的可选属性组成。

成员 描述
Name/Value 设置 Cookie 的名称及相对应的值,保存访问令牌。
Expires(期限) 设置 Cookie 的生存期。有两种存储类型的 Cookie :会话性持久性。Expires 属性缺省时,为会话性 Cookie,仅保存在客户端内存中,并在用户关闭浏览器时失效;持久性 Cookie 会保存在用户的硬盘中,直至生存期到或用户直接在网页中单击“注销”等按钮结束会话时才会失效。
Path 定义了 Web 站点上可以访问该Cookie的目录。
Domain(领域) 指定了可以访问该 Cookie 的 Web 站点或域。Cookie 机制并未遵循严格的 同源策略,允许一个子域可以设置或获取其父域的 Cookie。当需要实现单点登录方案时,Cookie 的上述特性非常有用,然而也增加了 Cookie 受攻击的危险,比如攻击者可以借此发动会话定置攻击。因而,浏览器禁止在 Domain 属性中设置.org、.com 等通用顶级域名、以及在国家及地区顶级域下注册的二级域名,以减小攻击发生的范围。
Secure 指定是否使用 HTTPS 安全协议发送 Cookie。使用 HTTPS 安全协议,可以保护 Cookie 在浏览器和 Web 服务器间的传输过程中不被窃取和篡改。该方法也可用于 Web 站点的身份鉴别,即在 HTTPS 的连接建立阶段,浏览器会检查 Web 网站的 SSL 证书的有效性(以前使用网上银行时是不是经常看到 SSL 证书这个东西,当然一般的网站是可以用户自己选择跳过)。
HTTPOnly 用于防止客户端脚本通过 document.cookie 属性访问 Cookie,有助于保护 Cookie 不被跨站脚本攻击窃取或篡改。

例子document.cookie="username=John Doe; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/";

2. Cookies 的流程

  • 发布 Cookie
    当用户试图访问某 Web 站点中需要认证的资源时,Web 服务器会检查用户是否提供了认证 Cookie,如果没有,则将用户重定向到登录页面。在用户成功登录后,Web 服务器会产生认证 Cookie,并通过 HTTP 响应中的 Set-Cookie 头发送给客户端,用于对用户随后的请求进行检查和验证,接着将用户重定向到初始请求的资源。

  • 检索 Cookie
    在用户随后的访问请求中,客户端浏览器检索 Path 和 Domain 等属性与用户请求资源相匹配的 Cookie,并将找到的 Cookie 通过 HTTP 请求中的 Cookie 头提交给Web服务器。

  • 验证 Cookie
    服务器提取客户端浏览器递交的Cookie,验证其中的访问令牌。若合法,则将访问请求的资源发送给客户端浏览器;反之则拒绝用户的访问请求。

3. Cookies 的安全威胁

  • Cookies 捕获/重放
    攻击者可以通过木马等恶意程序,或使用 跨站脚本 (cross-site scripting,XSS)攻击等手段偷窃存放在用户硬盘或内存中的Cookie。

因为同一个网站下的不同URL的 协议 + 域名/IP + 端口号是符合同源策略的。还是以论坛为例,假设其个人空间的 URL 逻辑为 http://a.com/username,那么 a 用户的个人空间地址为 http://a.com/a,b 用户的个人空间地址为 http://a.com/b

b 登陆之后在首页发表了一篇文章,添加了以下 js 代码:

let cookie = document.cookie;

那么在 a 登陆之后访问 b 的空间,b 就能拿到 a 的 cookies,从而可以代表 a 更改各种信息,这就是 XSS 攻击。

  • 恶意 Cookies
    Cookies 是文本文件, 一般情况下认为它不会造成安全威胁。 但是如果在 Cookies 中通过特殊标记语言,引入可执行代码,就很可能给用户造成严重的安全隐患。当页面存在 Cookies 代码注入漏洞,就可以利用修改 Cookies 来执行危险代码。

  • 会话定置
    会话定置( Session Fixation )攻击是指,攻击者向受害者主机注入自己控制的认证 Cookie 等信息,使得受害者以攻击者的身份登录网站,从而窃取受害者的会话信息。注入Cookie的方法包括:使用跨站脚本或木马等恶意程序;或伪造与合法网站同域的站点,并利用各种方法欺骗用户访问该仿冒网站,从而通过 HTTP 响应中的 Set-Cookie 头将攻击者拥有的该域 Cookies 发送给用户等。

  • CSRF攻击
    跨站请求伪造(Cross-Site Request Forgery,简称 CSRF)是指,攻击者可能利用网页中的恶意代码强迫受害者浏览器向被攻击的 Web 站点发送伪造的请求,篡夺受害者的认证 Cookies 等身份信息,从而假冒受害者对目标站点执行指定的操作。

4. Cookies 的安全防护

  • Web服务器端防护
  1. 加入 MAC 以进行完整性校验;
  2. 防止非法用户非法截获后的重放,可以让用户对相关信息进行数字签名,加强有效性验证;
  3. 对 Cookie 本身进行随机密钥加密,保证 Cookie 本身的信息安全。
  • 客户端浏览器防护
    对 Cookie 进行加密。在相应的系统目录下,只可看见一个与 Cookie 相关的加密文件,而且其中的 Cookie 文件,已被浏览器加密,用户不可见,在用户访问特定站点的时候,可由浏览器对 Cookie 文件进行调用并进行解密。

  • 主机的安全防护
    在浏览器产生 Cookie 加密文件时,在 Cookie 文件中加入一段主机的特征,生成一个双层加密的新的 Cookie 文件;在调用 Cookie 的时候,通过对 Cookie 文件进行主机特征的匹配,选择对内层的文件进行解密调用。


Session

web 的继续发展又引发出了其他用户疼点,比如页面间需要共享的信息多了, Cookies 的储存空间小的问题就出现了;再比如 Cookies 只能以文本格式存储极为不方便,同时每次的 HTTP 请求都会带上 Cookies 增加了宽带的消耗。

这时候 Session 被提出来了,它是一种利用服务端服务器端的机制。通过在 Cookies 中的 Session ID
与服务器校验创建一个被认证的会话,会话内的页面共享 Session 信息。它有以下优点:

  1. Session 的大小没有限制,因为存储在服务器上;
  2. Session 通过类似 Hashtable 的数据结构来保存,能支持任何类型的对象;
  3. 安全性比 Cookies 高,首先要攻破 Session 先要攻破 Cookie,同时 Session ID 是加密的,而 Session ID 需要登录后即创造会话后才有产生,难道比攻破 Cookie 要大得多;

但它依旧有缺点:

  1. Session 保存的东西越多,就越占用服务器内存,对于用户在线人数较多的网站,服务器的内存压力会比较大。
  2. 依赖于 Cookie,如果 Cookies 被禁用,则要使用 URL 重写即把 Session ID 拼接在 URL 后面,十分不安全。

由于 Session 是服务端(JAVA)的对象,并不存在于浏览器(JavaScript),要获取 Session 只能通过 Java 获取变成字符串传给浏览器,这里我们就不再展开讨论了。


Web Storage

随着 Html5 的到来,以上两个应用层面的缓存已经不能满足开发者的需求了,更便利的客户端缓存 Web Storage 出现了。它分为两项: Local StorageSession Storage

Web Storage 支持协议 + 域名/IP + 端口号的同源策略,非同源不能读取 Storage 里的内容,其属性都允许在浏览器中存储 key/value 对的数据,value 只能存储字符串数据。

那继上文提到的本地存储用户信息的问题, Cookies 因其特性不适合存储,Session 需要 JAVA 的帮助(在混合 APP 中可用利用),它们两都只适合做用户认证而不适合做信息存储,Web Storage 则是带来了本地数据库的功能。

Local Storage

localStorage 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去删除。localStorage 在PC端浏览器上能够提供5M左右的存储空间,在移动端浏览器上一般提供2.5M左右的存储空间。

语法

window.localStorage

  • 保存数据语法
    localStorage.setItem("key", "value");
  • 读取数据语法
    var lastname = localStorage.getItem("key");
  • 删除数据语法
    localStorage.removeItem("key");

局限

  • localStorage 在浏览器的隐私模式下面是不可读取的;
  • localStorage 本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡;
  • localStorage 不能被爬虫抓取到;
  • localStorage 的值类型限定为string类型;

Session Storage

sessionStorage 用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。

语法

window.sessionStorage

  • 保存数据语法
    sessionStorage.setItem("key", "value");
  • 读取数据语法
    var lastname = sessionStorage.getItem("key");
  • 删除数据语法
    sessionStorage.removeItem("key");

他们两同时含有这两个方法 .clear () 删除所有的数据,key (index) 获取某个索引的key。

Tips:在我做混合 APP 开发时(Hybird App),原生新打开的页面无法共享会话,即 sessionStorage 失效;


PWA

前面我们已经介绍完有关于 Cookies 一系的缓存机制,接下我们简单的谈谈 Google 与 W3C(万维网联盟)所力推的 PWA 以及为其服务的一系列缓存机制。(苹果虽然不太愿意支持,因为会影响它 APP 的抽成,但有 W3C 这个老大在,以后还是会普及的)

PWA 渐进式增强 web 应用, Google 在 2016 年提出概念,于 2017 年落地的 web 技术,而铺垫技术却在很早很早前就开启了(离线缓存概念)。目的就是为移动端利用提供的标准化框架,利用 web 技术实现有着和原生应用相近的用户体验。

大家在用手机浏览网页时应该能看到下面这个选项:

点击就可以在手机主屏生产 PWA 版本的离线应用,国外的 Facebook 、Twitter 等都实现得非常好了,它们是可以安装到设备的主屏幕的网络应用程序,而不需要用户通过应用商店,伴随着其他功能, 比如离线可用和接收推送通知。

Manifest

Manifest(Web 应用程序清单)是在一个JSON文本文件中提供有关应用程序的信息(如名称,作者,图标和描述),是 渐进式Web应用程序(PWA) 的 Web 技术集合的一部分。

Manifest 服务于 Service Workers、Cache Storage、Application Cache( Service Workers 取代 )、BackGround Services,这四项缓存都是依赖 Manifest 模块资源清单实现资源的管理的。

<link rel="manifest" href="/manifest.json">

至于这个清单怎么用这里就不细讲了,传送门

而 IndexedDB、Web SQL(废弃,被 IndexedDB 取代 ),则是前端的数据库,实际就是为了构建出统一的 APP 应用开发环境所做的铺垫。


关注我 Max_Law,学习更多前端知识。

0人推荐
随时随地看视频
慕课网APP