[[408517]]
打开浏览器的前端开发者工具中的Application部分,可以看到浏览器支持五种存储方式:localStorage、百题sessionStorage、从浏存储IndexedDB、览器WebSQL、控制Cookie。到种其中W3C 官方在 2011 年 11 月声明已经不再维护 Web SQL Database 规范,前端所以本次主要讨论另外的百题三类四种存储方式:Cookie、Storage、从浏存储IndexedDB。
Cookie是一个保存在浏览器中的简单的文本文件,该文件与特定的Web文档关联在一起,保存了该浏览器访问这个Web文档时的信息,当浏览器再次访问这个Web文档时这些信息可供该文档使用。(HTTP是无状态的协议,即HTTP协议本身不对请求和响应之间的通信状态进行保存,为了实现期望的保存状态功能,引入了cookie技术)
在了解Cookie组成之前先了解一下Cookie的整个请求流程,这个流程分为两类:一类是没有Cookie信息状态下的请求,另一类是存有Cookie状态下的请求。
通过上面的流程图可以看出,Cookie是在服务端生成的,经过查询资料了解到其是在从服务端发送的响应报文内的一个叫做Set-Cookie的首部字段信息,响应报文中有该首部字段则通知客户端保存Cookie,则Cookie的组成则跟Set-Cookie可以设置哪些值相关,目前主要有以下几类:
- const express = require('express');
- const app = express();
- app.get('/', (req, res) => {
- res.cookie('myCookie', 'myCookie', {
- expires: new Date(Date.now() + 900000),
- secure: true,
- httpOnly: true
- });
- res.send('get请求已经被处理');
- })
- app.listen(8090, () => {
- console.log('8090端口已经启动!!!');
- });
通过请求 http://127/.0.0.1:8090 来看看其结果:
第一次返回的Cookie结果
后续请求所带的Cookie信息
Cookie存储到浏览器端之后仍然可以对其进行读、写、删除,由于js对Cookie操作的支持并不是很友好,所以需要进行一些简单的封装。
- class CookieUtil {
- // 获取Cookie中的对应属性
- static get(name) {
- const cookies = document.cookie;
- const cookiesArr = cookies.split(';');
- for (let index = 0; index < cookiesArr.length; index++) {
- const presentCookieArr = cookiesArr[index].split('=');
- if (presentCookieArr[0] === name) {
- return presentCookieArr[1];
- }
- }
- return null;
- }
- // 设置对应的Cookie值
- static set(name, value, expires, path, domain, secure) {
- let cookieText = `${ name}=${ value}`;
- if (expires instanceof Date) {
- cookieText += `; expire=${ expires.toGMTString()}`;
- }
- if (path) {
- cookieText += `; path=${ path}`;
- }
- if (domain) {
- cookieText += `; domain=${ domain}`;
- }
- if (secure) {
- cookieText += `; secure`;
- }
- document.cookie = cookieText;
- }
- // 删除对应的Cookie
- static deleteCookie(name) {
- CookieUtil.set(name, '', new Date(0));
- }
- }
Web Storage的目的是解决通过客户端存储不需要频繁发送回服务器的数据时使用cookie的问题,其提供了cookie之外的存储会话数据的途径和跨会话持久化存储大量数据的机制,其主要有两个对象:localStorage和sessionStorage,localStorage是永久存储机制,sessionStorage是跨会话的存储机制。
sessionStorage是跨会话的存储机制,具有以下特点:
- // 使用方法存储数据
- sessionStorage.setItem('sessionName1', 'value1');
- // 使用属性存储数据
- sessionStorage.sessionName2 = 'value2';
- // 使用方法取得数据
- const sessionValue1 = sessionStorage.getItem('sessionName1');
- console.log('sessionValue1的值为:', sessionValue1);
- // 使用属性取得数据
- const sessionValue2 = sessionStorage.sessionName2;
- console.log('sessionValue2的值为:', sessionValue2);
- // 循环遍历sessionStarage
- for (let index = 0; index < sessionStorage.length; index++) {
- // 使用key()方法获得指定索引处的名称
- const key = sessionStorage.key(index);
- const value = sessionStorage.getItem(key);
- console.log('循环遍历结果:', key, value);
- }
- // 使用方法删除值
- sessionStorage.removeItem('sessionName1');
- // 使用delete删除值
- delete sessionStorage.sessionName2;
- // 使用clear()方法清空sessionStorage
- sessionStorage.clear();
localStorage是永久存储机制,具有以下特点:
- // 使用方法存储数据
- localStorage.setItem('localName1', 'value1');
- // 使用属性存储数据
- localStorage.localName2 = 'value2';
- // 使用方法取得数据
- const localValue1 = localStorage.getItem('localName1');
- console.log('localValue1的值为:', localValue1);
- // 使用属性取得数据
- const localValue2 = localStorage.localName2;
- console.log('localValue2的值为:', localValue2);
- // 循环遍历localStarage
- for (let index = 0; index < localStorage.length; index++) {
- // 使用key()方法获得指定索引处的名称
- const key = localStorage.key(index);
- const value = localStorage.getItem(key);
- console.log('循环遍历结果:', key, value);
- }
- // 使用方法删除值
- localStorage.removeItem('localName1');
- // 使用delete删除值
- delete localStorage.localName2;
- // 使用clear()方法清空localStorage
- localStorage.clear();
对于整个IndexedDB为上述图中所示:
一个域名下可以包含多个数据库;
一个数据库中包含多个对象仓库,就类似与Mysql一个库中有多张表一样。
每个对象仓库中包含多条数据记录。
IndexedDB是浏览器中存储结构化数据的一个方案,其设计几乎是完全异步的,主要有以下特点:
IndexedDB像很多其它数据库一样有很多操作,下面就通过实战的方式一起了解这些操作。
24.3.3.1 初始化数据库
第一步是初始化数据库,传入创建的数据库名和版本,获取对应的数据库操作实例。
- class IndexedDBOperation {
- constructor(databaseName, version) {
- this.atabaseName = databaseName;
- this.version = version;
- this.request = null;
- this.db = null;
- }
- // 数据库初始化操作
- init() {
- this.request = window.indexedDB.open(this.databaseName, this.version);
- return new Promise((resolve, reject) => {
- this.request.onsuccess = event => {
- this.db = event.target.result;
- console.log('数据库打开成功');
- resolve('success');
- };
- this.request.onerror = event => {
- console.log('数据库打开报错');
- reject('error');
- };
- this.request.onupgradeneeded = event =>{
- this.db = event.target.result;
- console.log('数据库升级');
- resolve('upgradeneeded');
- };
- });
- }
- }
24.3.3.2 对象仓库操作
数据是在对象仓库中存储的,创建好数据库后则需要创建所需的数据仓库
- class IndexedDBOperation {
- // ……
- // 创建数据仓库
- createObjectStore(objectStoreName, options) {
- let objectStore = null;
- if (!this.db.objectStoreNames.contains(objectStoreName)) {
- objectStore = this.db.createObjectStore(objectStoreName, options);
- }
- return objectStore;
- }
- }
24.3.3.3 数据操作
不管是关系型数据库还是非关系型数据库,CURD肯定是必不可少的,谁让我们是“CURD工程师”呢!!!
- class IndexedDBOperation {
- // ……
- // 新增内容
- add(objectStore, content) {
- objectStore.add(content);
- }
- // 获取内容
- get(objectStore, id) {
- const request = objectStore.get(id);
- return new Promise((resolve, reject) => {
- request.onsuccess = resolve;
- request.onerror = reject;
- });
- }
- // 更新内容
- update(objectStore, content) {
- const request = objectStore.put(content);
- request.onsuccess = event => {
- console.log('更新成功');
- };
- request.onerror = event => {
- console.log('更新失败');
- };
- }
- // 删除内容
- remove(objectStore, deleteId) {
- const request = objectStore.delete(deleteId);
- request.onsuccess = event => {
- console.log('删除成功');
- };
- request.onerror = event => {
- console.log('删除失败');
- };
- }
- }
24.3.3.5 调用代码
上面写了一个数据库的类,但是仍然不知道怎么调用呀,下面就用一个demo讲述其调用。
- class IndexedDBOperation {
- // ……
- // 打印全部数据
- printAllDataByCursor(objectStore) {
- const cursorRequest = objectStore.openCursor();
- cursorRequest.onsuccess = event => {
- const cursor = event.target.result;
- if (cursor) {
- console.log(`利用游标打印的内容,id为${ cursor.key}, 值为${ cursor.value}`);
- // 移动到下一条记录
- cursor.continue();
- }
- };
- }
- }
本文转载自微信公众号「执鸢者」,可以通过以下二维码关注。转载本文请联系执鸢者公众号。
责任编辑:武晓燕 来源: 执鸢者 浏览器存储
(责任编辑:时尚)
土地增值税酝酿立法 专家预计对房企影响有限 建议扩大适用税率
银保监会: 督促银行机构筑牢内控合规“防火墙” 夯实高质量发展根基
柳州市财政局“三步走”彻底摸清“家底” 提高国有资产的使用效益