一、Cookie
1.1 定义
1.2 Cookie组成
- NAME=VALUE
Cookie的名称和值,其中NAME是唯一标识cookie的名称,不区分大小写;VALUE是存储在Cookie里的字符串值,该值必须经过URL编码。
- Domain=域名
Cookie有效的域,发送到这个域的所有请求都会包含对应的Cookie。(若不指定则默认为创建Cookie的服务器的域名)
- Path=PATH
请求URL中包含这个路径才会把Cookie发送到服务器(若不指定则默认为文档所在的文件目录)
- Expires=DATE
Cookie的有效期,默认情况下,浏览器会话结束后会删除所有cookie。
- Secure
设置后仅在HTTPS安全通信时才会发送Cookie
- HttpOnly
设置后只能在服务器上读取,不能再通过JavaScript读取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端口已经启动!!!');
});
- 第一次返回的Cookie结果
2. 后续请求所带的Cookie信息
1.3 Cookie特点
- 每个Cookie不超过4096字节;
- 每个域中Cookie个数有限制,就拿最新版来说:IE和Edge不超过50个;Firefox不超过150个;Opera不超过180个;Safari和Chrome没有限制;
- Cookie超过单个域的上限,浏览器会删除之前设置的Cookie;
- 创建的Cookie超过最大限制,该Cookie会被静默删除;
- 可设置失效时间,没有设置则会话结束会删除Cookie;
- 每个请求均会携带Cookie,若Cookie过来会带来性能问题;
- 受同源策略限制
1.4 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
2.1 sessionStorage
- sessionStorage对象值存储会话数据,其生命周期会存储到浏览器关闭。(在该过程中刷新页面其数据不受影响)
- 浏览器在实现存储写入时使用同步阻塞方式,数据会被立即提交到存储。
- 独立打开同一个窗口同一个页面或一个Tab,sessionStorage也是不一样的。
- 存储空间大小限制为每个源不超过5M。
// 使用方法存储数据
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();
2.2 localStorage
- 生命周期是永久的,除非被清除,否则永久保存。
- 存储空间大小限制为每个源不超过5M。
- 受同源策略限制。
- 浏览器存储时采用同步存储方式。
// 使用方法存储数据
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
3.1 IndexedDB整个结构
对于整个IndexedDB为上述图中所示:
- 一个域名下可以包含多个数据库;
- 一个数据库中包含多个对象仓库,就类似与Mysql一个库中有多张表一样。
- 每个对象仓库中包含多条数据记录。
3.2 主要特点
- 键值对存储
在对象仓库中,数据以“键值对”形式保存,每个数据记录都有独一无二的主键。
- 异步
IndexedDB操作时不会锁死浏览器,用户依然可以进行其它操作。
- 支持事务
一些列操作步骤之中只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。
- 受同源策略限制
只能访问自身域名下的数据库,不能跨域访问数据库。
- 存储空间大
每个源都有存储空间的限制,而且这个限制跟浏览器有关,例如Firefox限制每个源50MB,Chrome为5MB。
- 支持二进制存储
不仅可以存储字符串,还可以存储二进制数据(ArrayBuffer和Blob)
3.3 数据库操作
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');
};
});
}
}
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;
}
}
3.3.3 数据操作
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('删除失败');
};
}
}
3.3.4 遍历内容
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();
}
};
}
}
3.3.5 调用代码
const indexedDBOperation = new IndexedDBOperation('dbName1', 1);
indexedDBOperation
.init()
.then(type => {
const objectStoreName = 'testObjectStore';
if (type === 'upgradeneeded') {
indexedDBOperation.createObjectStore(objectStoreName, {
keyPath: 'id'
});
}
const transaction = indexedDBOperation.db.transaction([objectStoreName], 'readwrite');
const objectStore = transaction.objectStore(objectStoreName);
indexedDBOperation
.get(objectStore, 1)
.then(event => {
if (event.target.result) {
indexedDBOperation.update(objectStore, {
id: 1,
name: '执鸢者+纸鸢'
});
console.log('数据库中已经存在', event.target.result, ',则进行更新操作');
}
else {
indexedDBOperation.add(objectStore, {
id: 1,
name: '执鸢者'
});
console.log('数据库中不存在,则进行添加');
}
})
.catch(console.log);
indexedDBOperation.printAllDataByCursor(objectStore);
transaction.onsuccess = event => {
console.log('事务操作成功');
};
transaction.onerror = event => {
console.log('事务操作失败');
};
transaction.oncomplete = event => {
console.log('整个事务成功完成');
}
})
.catch(console.log);
参考文献
- 浏览器数据库 IndexedDB 入门教程
- javascript高级程序设计4
- IndexedDB API
1.如果觉得这篇文章还不错,来个分享、点赞吧,让更多的人也看到
2.关注公众号执鸢者,领取学习资料(前端“多兵种”资料),定期为你推送原创深度好文
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!