客戶端瀏覽器存儲技術涉及到幾個點分別是
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的用戶體驗
如:弱網環境,離線環境,能否加載基本交互界面提升用戶體驗等等
未完待續…