在JavaScript中,本地存储是一种在用户的浏览器上存储数据的方式,它允许网页在不与服务器进行额外数据传输的情况下保留跨会话信息。主要有三种本地存储方式:sessionStorage、localStorage、cookie与indexDB。
javaScript有4种数据存储方式,分别是:
sessionStoragelocalStoragecookierindexDB一. javaScript本地存储之 sessionStorage
sessionStorage仅在当前会话下有效,关闭页面或浏览器后被清除,也就是说sessionStorage只存在于窗口(页面)活跃期,一旦窗口关闭,sessionStorage将会删除数据。
sessionStorage的方法有以下几个
setItem(key,value) 设置数据getItem(key) 获取数据removeItem(key) 移除数据clear() 清除所有值sessionStorage实例:
// 添加数据window.sessionStorage.setItem("name","李四")window.sessionStorage.setItem("age",18)// 获取数据console.log(window.sessionStorage.getItem("name")) // 李四// 清除某个数据window.sessionStorage.removeItem("gender")// 清空所有数据window.sessionStorage.clear()
二. javaScript本地存储之 localStorage
localStorage是HTML5中引入的技术,用于在用户的浏览器上长期存储数据,直到用户手动删除。与sessionStorage类似,但localStorage存储的数据没有过期时间。它同样提供了setItem、getItem、removeItem和clear方法来操作数据。
localStorage的方法有以下几个
setItem(key,value) 设置数据getItem(key) 获取数据removeItem(key) 移除数据clear() 清除所有值// 存储数据localStorage.setItem("name", "张三");localStorage.setItem("age", 20);localStorage.setItem("gender", "男");// 获取数据console.log(localStorage.getItem("name")); // 输出: 张三// 删除数据localStorage.removeItem("gender");// 清除所有数据localStorage.clear();
localStorage还可以通过添加时间戳和过期时间来手动设置数据的失效时间。由于localStorage只能存储字符串,因此在存储对象时需要将其转换为JSON字符串,并在读取时解析。
Storage.prototype.setExpire = (key, value, expire) => {let obj = {data: value,time: Date.now(),expire: expire};//localStorage 设置的值不能为对象,转为json字符串localStorage.setItem(key, JSON.stringify(obj));}Storage.prototype.getExpire = key => { let val = localStorage.getItem(key); if (!val) { return val; } val = JSON.parse(val); if (Date.now() - val.time > val.expire) { localStorage.removeItem(key); return null; } return val.data;}//使用方法localStorage.setExpire('userId','zhangsan',5000);window.setInterval(()=>{ console.log(localStorage.getExpire("userId"));},1000)总结持久化存储,就算窗口关闭也依然保留,除非手动删除页面刷新数据不丢失存储范围一般不超过5M同一浏览器支持多窗口(多页面)共享假设同一个浏览器打开同源的三个页面,.com/a.html;.com/b.html;**.com/c.html;那么这三个窗口是可以共享localstorage的以键值对的形式保存以localStorage.setItem(key,valueStr)保存值,valueStr必须是字符串,要存储对象必须先字符串序列化,通过JSON.stringify(),取值的时候在通过JSON.parse()还原以键取值以value=localStorage.getItem(key)获取值,如果不存在,返回null受同源策略的限制不同源的页面不能访问localStorage.比如在浏览器里面打开www.baidu.com/index.html存储了一个localStorage;同样在浏览器里面打开的www.ali.com/index.html就无法访问到。因为他两不同源操作localstorage时,会触发非当前页面的storage事件我们在A页面设置了localStorage,就会触发其他页面的storage事件,这样方便我们监听storage的状态,做出后续的响应。比如在登录页完成登录,把登录成功的标志logSuc存储在localStorage里面,localStorage.setItem(‘logSuc’,true);然后个人中心页面就可以通过storage事件判断出已经登录,并读取个人信息进行预加载支持单个删除和全部删除,分别通过removeItem(key)和clear()方法实现
三. javaScript本地存储之 cookie
Cookie 是一些数据, 存储于你电脑上的文本文件中,用于存储 web 页面的用户信息Cookie 数据是以键值对的形式存在的,每个键值对都有过期时间。如果不设置时间,浏览器关闭,cookie就会消失,当然用户也可以手动清除cookieCookie每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题Cookie内存大小受限,一般每个域名下是4K左右,每个域名大概能存储50个键值对通过访问document.cookie可以对cookie进行创建,修改与获取。默认情况下,cookie 在浏览器关闭时删除,你还可以为 cookie的某个键值对 添加一个过期时间,如果设置新的cookie时,某个key已经存在,则会更新这个key对应的值,否则他们会同时存在cookie中
// 设置cookiedocument.cookie = "username=orochiz"document.cookie = "age=20"// 读取cookievar msg = document.cookieconsole.log(msg) // username=orochiz; age=20// 添加过期时间(单位:天)var d = new Date() // 当前时间 2019-9-25var days = 3 // 3天d.setDate(d.getDate() + days)document.cookie = "username=orochiz;"+"expires="+d// 删除cookie (给某个键值对设置过期的时间)d.setDate(d.getDate() - 1)console.log(document.cookie)
四. javaScript本地存储之 indexDB
前面讲的存储方式都是以字符串的形式在存储,假设我们现在的需求是要存储大量结构化的数据怎么办,那就用indexDB这是一个正儿八经的数据库,做服务端的同学都了解数据库,这个跟数据库没啥的区别。只不过人家存在于客户端而已。那既然这样,说明人家优点很多,包括以下几点储存量理论上没有上限所有操作都是异步的,相⽐ LocalStorage 同步操作性能更⾼,尤其是数据量较⼤时原⽣⽀持储存 JS 的对象是个正经的数据库,意味着数据库能⼲的事它都能⼲-那他具体怎么操作呢,都说了人家是数据库,那就按数据库的一般操作流程来呗建立连接打开数据库,操作数据库增删改查,只不过可能为了更好地使用客户端,可能某些步骤或者程序上做了一些微调,那我们就实地操作一个class DBOpration{ constructor() { this.db = null } getType(val) { let type = typeof val == 'object' return type } // 打开数据库 open(parm) { return new Promise((res, rej) => { let request = window.indexedDB.open(parm.dbName, parm.versions) request.onerror = function(event) { console.log(event) // 错误处理 rej() console.log(' 打开数据库报错') } request.onsuccess = event => { this.db = request.result console.log('打开数据库成功') res() // 成功处理 } // 数据库更新时的回调 request.onupgradeneeded = event => { this.db = event.target.result this.createdDB(parm) } }) } // 创建库表 createdDB(parm) { console.log(parm) if (!this.db.objectStoreNames.contains(parm.objName)) { this.db.createObjectStore(parm.objName, { keyPath: 'id' }) // objectStore.createIndex("data", "data", { unique: false }); // unique name可能会重复 } } // 新增(不需要使用) async add(parm = { dbName, objName, param, response }) { await this.open(parm) // await this.upgrade(dbName); return new Promise((res, rej) => { let type = this.getType(parm.param) let type1 = this.getType(parm.response) let transaction = this.db.transaction([parm.objName], 'readwrite') let objectStore = transaction.objectStore(parm.objName) // 用户读取数据,参数是主键 let request = objectStore.add({ id: type ? JSON.stringify(parm.param) : parm.param, data: type1 ? JSON.stringify(parm.response) : parm.response }) console.log(request) request.onsuccess = function(event) { res(event) console.log('数据写入成功') } request.onerror = function(event) { rej() console.log('数据写入失败') } }) } // 读取库表数据 async read(parm = { dbName, objName, param, response }) { await this.open(parm) return new Promise((res, rej) => { let type = this.getType(parm.param) var transaction = this.db.transaction([parm.objName]) var objectStore = transaction.objectStore(parm.objName) // 用户读取数据,参数是主键 var request = objectStore.get(type ? JSON.stringify(parm.param) : parm.param) request.onerror = function(event) { console.log('事务失败') rej() } request.onsuccess = function(event) { if (request.result) { let data = JSON.parse(request.result.data) res(data) } else { res(request.result) console.log('未获得数据记录') } } }) } // 修改库表数据,但是因为创建数据库时直接创建了库表,所以无论是添加还是修改都掉这个就可以了. async update(parm = { dbName, objName, param, response }) { await this.open(parm) return new Promise((res, rej) => { let type = this.getType(parm.param) let type1 = this.getType(parm.response) console.log(parm) var request = this.db .transaction([parm.objName], 'readwrite') .objectStore(parm.objName) .put({ id: type ? JSON.stringify(parm.param) : parm.param, data: type1 ? JSON.stringify(parm.response) : parm.response }) request.onsuccess = function(event) { res() console.log('数据更新成功') } request.onerror = function(event) { rej() console.log('数据更新失败') } }) } // 删除某个表的数据 async remove(parm = { dbName, objName, param, response }) { await this.open(parm) return new Promise((res, rej) => { let type = this.getType(parm.param) var request = this.db .transaction([parm.objName], 'readwrite') .objectStore(parm.objName) .delete(type ? JSON.stringify(parm.param) : parm.param) request.onsuccess = function(event) { res() console.log('数据删除成功') } }) } }let db=new DBOpration()//创建数据库实例//接下来增删改查调取对应的方法就行
总结:localStorage,sessionStorage,cookie,indexDB不同存储方式的使用场景
cookie,适用于标记用户与跟踪用户行为
localStorage,适用于长期保存用户的本地数据,比如token
sessionStorage,适合敏感账号一次性登录
indexDB,适合存储大量结构化数据,比如富文本编辑器的编辑历史保存等
这四种本地存储方式都保存在浏览器端,但它们有以下不同点:
cookie数据在每次HTTP请求中都会被发送到服务器,而sessionStorage和localStorage仅在本地保存。
cookie数据大小限制为4KB,而sessionStorage和localStorage可以达到5MB或更大。
sessionStorage仅在当前会话有效,localStorage始终有效,cookie则在设置的过期时间之前有效。
sessionStorage不在不同的浏览器窗口中共享,而localStorage和cookie在所有同源窗口中共享。
indexDB是数据库,可以储存大量数据,原⽣⽀持储存 JS 的对象,所有操作都是异步的,相⽐ LocalStorage 同步操作性能更⾼本地存储提供了一种方便的方式来持久化用户数据,但需要注意的是,它们都遵循同源策略,不同的网站之间不能共用相同的存储空间。此外,由于localStorage和sessionStorage仅支持字符串类型的存储,因此在存储非字符串类型的数据时需要进行类型转换。