客户端浏览器存储技术涉及到几个点分别是
localstorage、cookie、sessionstorage、indexdb,serviceWorker
cookie:
1,存储数据4KB左右
2,需要设置过期时间
3,httponly
应用场景
1,用于与服务器发生交互场景
cookie解决最重要的一个问题就是HTTP的无状态请求,即通过cookie让服务器识别访问者是谁以此来保持某些特定的状态
如:客户端通过http访问服务器,此为一次会话,如果你想下次访问让服务器知道你是谁,那么最常用的方式就是启用session,将一个sessionid通过http response set-cookie的方式写入客户端cookie中,当客户端下次访问服务器,通过sessionid自然知道此次请求来自于哪个客户端
2,浏览器自身通过js读写本地cookie,进行数据存储
如:通过document.cookie读写
优化总结
1,当前cookie除了用作保持http状态以外几乎不做数据存储方案
2,重点,如果启用了cookie切往cookie中存放了数据,假如4KB数据量,那么因为我们访问网站必须要请求大量的静态文件,其次因为每次请求都会携带cookie数据,这个时候额外的流量损耗
会随着访问次数数目变大而增大,对于大公司来讲是一笔不小的额外经济开销,解决方案就是静态资源放在cdn服务器上,且相对于主站来说,域名独立,这个时候当我们去请求资源的时候不需要附带cookie信息
3,设置httponly
很重要,为了防止不法分子劫持cookie用来做安全攻击
js写入cookie
js读取cookie
document.cookie
localStorage
1,html5专门设计出用来浏览器存储
2,以chrome为例是5M
,不同浏览器会有差别,如IE
3,仅在客户端使用不和服务端通信
4,接口封装较为完善
5,浏览器缓存常用解决方案之一
js写入localStorage
js读取localStorage
sessionStorage
1,会话级浏览器存储
-也就是当前本次和服务器发生交互存在的存储,关掉浏览器就释放掉存储内容
2,大小5M
3,仅在客户端使用,不和服务端进行通信
4,接口较为完善
5,对于表单信息的维护(1、表单填写刷新后数据保存
,2、本次会话多页面数据共享
)
indexDB
低级API,可存储大量客户端结构化数据,使用相关API来进行数据高性能索引,web Storage少量数据有用,大量结构化数据存储,很明显不行,IndexDB这种客户端的数据库级的存储更合适(构建web应用的离线版本
)
//打开数据库
function openDB(name, callback) {
var request = window.indexedDB.open(name)
request.onerror = function (e) {
console.log("open indexBD error")
}
request.onsuccess = function (e) {
myDB.db = e.target.result
}
监听数据库版本变化0->1,1->2…
request.onupgradeneeded = function (e) {
myDB.db = e.target.result //将打开成功的数据库对象赋值给mydb
callback && callback()
var store = myDB.db.createObjectStore('books', {
keyPath: 'isbn'
})
//创建索引
var titleIndex = store.createIndex("by_title", "title", {
unique: true
})
var autorIndex = store.createIndex("by_author", "author")
//初始化数据
store.put({
title: "titleOne",
author: "fred",
isbn: 1213345
})
store.put({
title: "titletwo",
author: "harry",
isbn: 234567
})
store.put({
title: "titlethree",
author: "fuck",
isbn: 345567
})
}
}
var myDB = {
name: "MYDB",
version: 1,
db: null //成功返回对象
}
openDB(myDB.name, function () {
// myDB.db.close() //关闭数据库
// window.indexedDB.deleteDatabase(myDB.db) // 删除数据库
})
//indexDB 事务->跟object store 建立关系操作数据
function addData(db) {
console.log("db", db)
var transaction = db.transaction("books", "readwrite") //指定操作某个数据库,并设置读写权限
var store = transaction.objectStore("books")//关联数据库
//获取通过key获取一条数据
var req = store.get(1213345)
req.onsuccess = function (e) {
console.log("get a data", e.target.result)
}
//添加一条数据
store.add({
title: "titlefour",
author: "不告诉你",
isbn: 222222
})
}
setTimeout(function () {
addData(myDB.db)
}, 2000)
service Workers(实现PWA标准的方案之一)
Server Worker
是一个脚本
,浏览器独立于当前网页,将其在后台运行,为实现一些不依赖页面或交互特性的特性打开大门,在未来这些特性将包括消息推送
,背景后台同步
,定位
,但他将推出首要的特性就是拦截和处理网络请求
的能力,包括以编程的方式来管理被缓存的响应
--------实现离线应用
(淘宝当前大规模使用的方案
)
应用场景:
1,
使用拦截和网络请求的能力实现离线应用
2,
在后台运行同时能和页面通信的能力,实现大规模后台数据处理
3,
经典解决方案,页面间通信
Demo代码:[email protected]:sunhailiang/serviceWorker.git
Service Worker生命周期:
查看Service Worker运行状态
1、谷歌内置Service Worker查看(带有service worker站点的浏览记录)
chrome://serviceworker-internals
2、查看当前正在运行的Service Worker
chrome://inspect/#service-workers
==1、离线应用-缓存
1,新建项目文件夹
- a:新建index.html
- b:新建app.js
- c:新建serverWorker.js
index.html
app.js
if(navigator.serviceWorker){
//注册serviceWorker,并定义作用范围
navigator.serviceWorker.register("./serviceWorker.js",{scope:'./'}).then((reg)=>{
console.log("regist success")
}).catch((e)=>{
console.log("regist error")
})
}else{
alert("service Worker is not supported")
}
serverWorker.js
self.addEventListener("install", function (e) {
e.waitUntil(caches.open('app-v1').then((cache) => { //worker开启前作基础数据缓存
console.log("open cache")
return cache.addAll([ //添加离线缓存资源以备实现基础离线交互
'./app.js',
'./main.css',
'./index.html'
])
}))
})
self.addEventListener("fetch",function(event){ //获取离线缓存资源
event.respondWith(caches.match(event.request).then((res)=>{ /拦截资源请求,检查cache缓存是否存在
if(res){
return res //cache缓存有匹配资源则返回缓存资源
}else{
//如果没有通过网络fetch资源
fetch(URL).then((res)=>{
if(res){
//如果从网络中请求到相关资源就缓存起来以便下次直接用缓存
// caches.addAll(res)
}else{
//提示用户请求失败
}
})
}
}))
})
执行结果
首次请求资源加载速度
缓存读取响应速度和资源来源
==2、消息推送-页面通信
新建项目:msgServiceWorker
- 1、新建index.html
- 2、新建app.js
- 3、新建serviceWorker.js
index.html
<body>
<ul id="msgBox"></ul>
<input type="text" id="msg-input">
<button id="send-msg-button">发送消息</button>
</body>
<script src="./app.js"></script>
app.js
if (navigator.serviceWorker) {
//绑定事件
let btn = document.getElementById("send-msg-button")
let val = document.getElementById("msg-input")
let box = document.getElementById("msgBox")
btn.addEventListener("click", function () {
//发送消息给serviceWorker
navigator.serviceWorker.controller.postMessage(val.value)
})
//监听信息
navigator.serviceWorker.addEventListener("message",function(e){
box.innerHTML+="<li>"+event.data.message+"</li>" //将信息发送给被监听的所有客户端
})
//注册serviceWorker,并定义作用范围
navigator.serviceWorker.register("./serviceWorker.js", { scope: './' }).then((reg) => {
console.log("regist success", reg)
}).catch((e) => {
console.log("regist error")
})
} else {
alert("service Worker is not supported")
}
serviceWorker.js
self.addEventListener("message", function (e) {
let promise = self.clients.matchAll().then((clientList) => {
let senderId = e.source ? e.source.id : 'unknown';
clientList.forEach(client => {
if (client.id === senderId) {
return //当前发送页面直接返回不做处理
} else {
client.postMessage({ //向其他其他被监听页面广播主页发送的信息
client: senderId,
message: e.data
})
}
})
})
e.waitUntil(promise)
})
结果
1,明确被监听的页面
2、分别在监听的页面发一条信息另外另个被监听页面同时收到信息
pwa(标准)
特点
1,可靠:在没有网络的环境中也能提供基本的页面访问,不会出现“未连接到互联网”页面
2,快速:针对网页渲染以及网络数据访问有较好优化
3,融入:应用可以被添加到手机桌面,并且有全屏和推送等特性
检测工具
lighthouse(谷歌商店直接添加插件)
PWA开发框架(vue)
https://lavas.baidu.com/guide
Progressive Web Apps(渐进式web应用)
是一种Web App新模型,并不是指具体某一种前沿的技术或知识点,这是一个渐进式Web App通过Web 新特性,配合优秀的UI交互设计,逐步增强Web App的用户体验
如:弱网环境,离线环境,能否加载基本交互界面提升用户体验等等
未完待续…