缓存:常打交道的老朋友
前端缓存世界主要分为两大块:HTTP缓存 && 浏览器缓存
一、HTTP缓存
客户端向服务器请求资源时,会先抵达浏览器缓存,如果浏览器有“要请求资源”的副本,可直接从浏览器缓存中提取而不是从原始服务器中提取资源。
1、强缓存
强制缓存在缓存数据未失效的情况下,会直接使用浏览器的缓存数据,不会再向服务器发送任何请求。
未失效:即Cache-Control的max-age没有过期或者Expires的缓存时间没有过期
1、Cache-Control
Cache-Control:max-age=xx; 表示缓存内容将在 xxx 秒后失效。
Cache-Control:no-store; 完全禁用缓存。
Cache-Control:no-cache; 在使用缓存之前先与服务器确认资源是否更改。如果资源已更改,服务器会返回新的资源;如果资源没有更改,服务器可能返回 304 Not Modified 状态码,表示可以使用缓存的版本。(这个属性值是匹配协商缓存使用)
2、Expires
缓存过期时间,用来指定资源到期的时间。在响应 http 请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。
其实这两者差别不大,区别就在于 Expires 是 http1.0 的产物,Cache-Control 是 http1.1 的产物,两者同时存在的话,Cache-Control 优先级高于 Expires~
2、协商缓存
当第一次请求时,服务器的响应头中没有设置 Cache-Control 和 Expires 字段,或者 Cache-Control 被设置为 no-cache,浏览器就会认为该资源不适合强缓存,而是使用协商缓存的方式来处理。
在使用协商缓存时,浏览器在发送第二次请求时会携带一些条件,比如上次请求时服务器返回的 ETag 或 Last-Modified 字段。服务器在接收到这些条件后,会进行比较,并根据资源是否有更新来决定返回的状态码。
1、Etag
Etag/If-None-Match: Etag属于HTTP 1.1属性,它是由服务器(Apache或者其他工具)生成返回给前端,用来帮助服务器控制Web端的缓存验证。
2、Last-Modifed
Last-Modifed/If-Modified-Since: Last-Modifed是服务器端文件的最后修改时间。
补充:
-
实际应用中,协商缓存需要与强缓存一起使用,否则在没有强缓存设置的情况下,协商缓存就没有意义。强缓存可以让浏览器在一定时间内直接使用缓存,不与服务器进行交互,而协商缓存则用于在强缓存失效时与服务器进行验证资源是否有更新。
-
如果不启用强缓存的话,但设置了Last-Modified时,那么浏览器默认会采用一个启发式的算法,即启发式缓存。通常会取响应头的Date_value - Last-Modified_value值的10%作为缓存时间。
二、浏览器缓存
1、sessionStroage
用于临时保持同一窗口的数据,窗口关闭数据也将删除,sessionStroage中一般浏览器支持的是5M大小
let info = {
name: 'Tiboo',
number: '1204914',
guid: '00123'
}
存储: 将对象转换为JSON字符串
sessionStroage.setItem('info', JSON.stringify(info));
读取: 将JSON字符串转换为对象
let infoData = JSON.parse(sessionStroage.getItem('info'))
2、localStroage
本地存储,同时不受时间限制的数据存储,localStorage中一般浏览器支持的是5M大小
let info = {
name: 'Tiboo',
number: '1204914',
guid: '00123'
}
存储: 将对象转换为JSON字符串
localStroage.setItem('info', JSON.stringify(info));
读取: 将JSON字符串转换为对象
let infoData = JSON.parse(localStroage.getItem('info'))
3、cookie
存储web页面的用户信息, 通过设置有效期删除存储数据。
每个值大小不能超过4kb, 每个web站点设置的cookie 数量不能超过20个,若超过则最早期的cookie将被自动删除。
**创建cookie:**
setCookie('b2bPartnerId', '22222')
// 设置过期时间为30天
setCookie(name, value) {
let Days = 30;
let exp = new Date();
exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
document.cookie = name + '=' + escape(value) + ';expires=' + exp.toGMTString();
}
**读取cookie:**
let partnerId = getCookie('b2bPartnerId')
getCookie(name) {
let arr = document.cookie.match(reg)
let reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)');
if (arr) {
if (arr.length) {
return unescape(arr[2]);
} else {
return null;
}
} else {
return null;
}
}
小坑tips: cookie值的设置与电脑的性能有关系,在设置完cookie值后,立即从cookie中获取值,此时可能出现拿到的值为空。
4、IndexedDB
indexedDB存储比较适合键值对较多的数据,相对需要存储多个字段的场景,使用localStorage存储,每次写入和写出都要字符串化和对象化,较为很麻烦,如果使用indexedDB会轻松很多,因为无需数据转换。
5、WebSql
HTML5 Web SQL Database和indexedDB都是本地数据库数据存储,Web SQL Database数据库要出来的更早。
W3C宣布舍弃Web SQL database草案,官方说法是因为无法走标准化的流程