HTML本地存储方式有:cookie、localStorage、sessionStorage、indexDB和HTML5离线缓存
cookie
cookie一般用于保存用户的相关信息,并实现维持会话的功能。服务器响应请求时在请求头里添加Set-Cookie字段,浏览器将该字段保存为本地的cookie。cookie绑定在特定域名下,当再次向该域名发送请求时,请求头里将包含该cookie。每个域名的cookie总数是有限的,IE7+、Firefox限制每个域最多50个,Chrome没有作硬性规定。同时每个cookie的大小也会被限制在 4KB 以内。JavaScript中可以通过document.cookie
进行cookie的读写。
请求头里的cookie:
cookie在浏览器中:
图中HTTP选项打了勾的,浏览器不能操作该cookie,只能读不能写。Secure打了勾的,只能在https下作用。
localStorage与sessionStorage
localStorage和sessionStorage是HTML5新提供的本地缓存的对象。相比于以前的cookie,localStorage和sessionStorage能够存储 5M 的数据,存储容量大幅度提升。但这两者也有不同之处:
方式 | 区别 |
---|---|
localStorage | 没有存储时间的限制 |
sessionStorage | 只存储于一个会话周期内 |
locaStorage:
//存储数据
localStorage.setItem("a",1); //或者localStorage.a = 1;
//取出数据
localStorage.getItem("a"); //或者localStorage.a
//删除数据
localStorage.removeItem("a");
sessionStorage:
//存储数据
sessionStorage.setItem("a",1); //或者sessionStorage.a = 1;
//取出数据
sessionStorage.getItem("a"); //或者sessionStorage.a
//删除数据
sessionStorage.removeItem("a");
indexDB
indexDB是保存在浏览器中的数据库。与MySQL等数据库不同的是,indexDB使用对象来保存数据,而不是表。一个indexDB数据库,就是一组位于相同命名空间下对象的集合。
indexDB的特点:
键值对储存、异步操作、事务、同域限制、储存空间大、支持二进制储存
使用indexDB:
function IndexedDB(db){
this.name = db.name; // 数据库名
this.version = db.version || 1; //数据库版本
this.tables = db.tables || []; //数据库表
this.openDB(this.name, this.version ,this.tables);
}
IndexedDB.prototype = {
constructor : IndexedDB,
indexedDB : indexDB = window.indexedDB || window.msIndexedDB || window.mozIndexedDB || window.webkitIndexedDB,
openDB : function(name, version, tables){
var _this = this;
var version=version;
var request=this.indexedDB.open(name, version);
request.onerror=function(e){
console.log(e.currentTarget.error.message);
};
request.onsuccess=function(e){
_this.db=e.target.result;
};
request.onupgradeneeded=function(e){
_this.db=e.target.result;
// 创建表
for(var i in tables){
if(!_this.db.objectStoreNames.contains(tables[i].name)){
var store = _this.db.createObjectStore(
//tables[i].key !== undefined ? {keyPath:tables[i].key} : { autoIncrement: true }
tables[i].name, {keyPath:tables[i].key} );
// 创建索引
if(tables[i].index !== undefined && tables[i].index instanceof Array){
for(var k in tables[i].index){
store.createIndex(tables[i].index[k].name + "",tables[i].index[k].name,{ unique : tables[i].index[k].unique });
}
}
else if(tables[i].index !== undefined){
store.createIndex(tables[i].index.name,tables[i].index.name,{ unique : tables[i].index.unique || true});
}
}
}
console.log('DB version changed to '+version);
};
},
/**
* 添加数据
*/
addData : function(storeName, data){
var transaction=this.db.transaction(storeName,'readwrite');
var store=transaction.objectStore(storeName);
// 多个数据
if(data instanceof Array){
for(var i=0;i<data.length;i++){
store.put(data[i]);
}
// 单个数据
}else{
debugger
store.put(data);
}
},
/**
* 获取数据
*/
getData : function(storeName, keys, index){
var transaction=this.db.transaction(storeName,'readonly'),
store=transaction.objectStore(storeName),
data = [],
hasTable = false,
hasIndex = false,
useCursor = false,
request;
// 判断表和索引是否存在
this.tables.forEach(element => {
if(element.name === storeName){
hasTable = true;
}
if(element.index instanceof Array){
element.index.forEach(element=>{
if(element.name === index){
hasIndex = true;
}
});
}
});
if(!hasTable){
return data;
}
if(hasTable && hasIndex){
store=store.index(index);
}
if(Object.prototype.toString.call(keys) === "[object Array]"){
for(var i=0;i<keys.length;i++){
request = store.get(keys[i]);
}
}else if(Object.prototype.toString.call(keys) === "[object Object]" && hasIndex){
useCursor = true;
if(keys.min !== null && keys.max === null){
request=store.openCursor(IDBKeyRange.lowerBound(keys.min,keys.minOpen));
}else if(keys.value1 === null && keys.value2 !== null){
request=store.openCursor(IDBKeyRange.upperBound(keys.max,keys.maxOpen));
}else if(keys.value1 !== null && keys.value2 !== null){
request=store.openCursor(IDBKeyRange.bound(keys.min,keys.max,keys.minOpen,keys.maxOpen));
}else{
return data;
}
}else if(typeof keys !== "undefined"){
request = store.get(keys);
}
request.onsuccess = function(e){
if(useCursor){
var cursor=e.target.result;
if(cursor){
data.push(cursor.value);
cursor.continue();
}
}else{
data.push(e.target.result);
}
}
return data;
},
/**
* 删除数据
*/
deleteData : function(storeName,keys){
var transaction = this.db.transaction(storeName,'readwrite'),
store = transaction.objectStore(storeName);
if(keys instanceof Array){
for(var i=0;i<keys.length;i++){
request = store.delete(keys[i]);
}
}else{
request = store.delete(keys);
}
},
/**
* 关闭数据库
*/
close : function(){
this.db.close();
},
/**
* 删除数据库
*/
remove : function(){
indexedDB.deleteDatabase(this.name);
}
}
/**
* 示范
*/
var db = new IndexedDB({
name : "test", // 数据库名
version : 1, // 数据库版本号
tables : [ // 数据库表。数组对象
{
name :"students", // 数据库表名
key : "id", // keyPath
index:[{ // 索引
name : "name", // 索引名称
unique : false, // 是否唯一
},
{
name : "id",
unique : true,
}]
},
{
name :"teacher",
key : "id"
}
]});
var data = [
{
id : 001,
name : "zhangshan",
score : 99
},
{
id : 002,
name : "lishi",
score : 89
},
{
id : 003,
name : "wangwu",
score : 79
},
{
id : 004,
name : "zhouliu",
score : 73
},
{
id : 005,
name : "tianqi",
score : 95
}
];
setTimeout(function(){
db.addData("students",data);
var data = db.getData("students",{
min : 001,
max : 004,
minOpen : true,
maxOpen : false
},"id");
console.log(data);
data = db.getData("students",001);
console.log(data);
data = db.getData("students","zhouliu","name");
console.log(data);
db.deleteData("students",001);
db.close();
//db.remove();
},0);
HTML5离线缓存
HTML5为本地存储提供了离线缓存的方法。通过给html标签添加mainfest属性,告诉浏览器使用缓存。并在服务器端配置mainfest文件,配置缓存的内容。可以通过修改mainfest文件内容、清除浏览器缓存、js控制来更新缓存。使用HTML5缓存,可以在没有网络的情况下访问页面,提高页面响应速度,减轻服务器负载并且可以缓存任何文件。
使用HTML5缓存:
设置mainfest文件格式
在nginx服务器中,在配置目录下的mime.types中type里添加一行
text/cache-manifest manifest
添加mainfest文件
mainfest文件格式:
CACHE MANIFEST CACHE: #需要缓存的文件 index.js index.css NETWORK: #不需要缓存的文件 index.html FALLBACK: #访问缓存失败后,备用访问的资源,第一个是访问源,第二个是替换文件 index.html 404.html
HTML页面中使用mainfest
<!DOCTYPE html> <html lang="en" manifest="cache.manifest"> <head> <title>Document</title> <link rel="stylesheet" href="index.css"> <script src="index.js"></script> </head> <body> </body> </html>
在线状态检测:
window.navigator.onLine
更新缓存:
window.applicationCache.update