HTML5 離線存儲
本章介紹一下 HTML5 新增的離線存儲特性 Localstorage,主要包括 Localstorage 的發展史、兼容性、優缺點以及使用場景。
說到 Localstorage,為什么要使用 Localstorage 呢?
因為開發程序當然就要存儲數據了,但是 Web 開發場景比較特殊,數據正常情況下是要通過 HTTP 協議發送給服務器端,存儲在服務器上,但是呢,如果所有數據都存到服務器一方面會浪費服務器資源,另一方面也會降低網頁響應速度,所以設計網頁時會抽取一些不太重要的或者臨時性的數據使用離線存儲方式放在瀏覽器上。
總的來說,Localstorage 是一個簡單的離線存儲技術,通過官方提供的增刪改查的 API 可以方便的操作它,需要考慮的難點是每個瀏覽器的容量限制,使用時做好容錯即可。
1. 離線存儲發展史
在早期的互聯網發展中,瀏覽器制定了不同的標準用于存儲離線數據,其中比較出名的有微軟 IE 瀏覽器的 userData(單個頁面可存儲 64 kb)、Adobe 的 flash6 中的 flash-cookies(允許存儲 100kb)、flash8 中的 externalinterface、Google 的 gears,不幸的是這些技術沒有統一的標準,而且只適用于單一的瀏覽器,不能跨平臺,所以沒有收錄在 HTML 標準中。HTML5 之前,Cookie 是唯一在 HTML 標準中用于離線存儲的技術,但是 Cookie 有一些不太友好的特征限制了它的應用場景:
- Cookie 會被附加在 HTTP 協議中,每次請求都會被發送到服務器端,增加了不必要的流量損耗
- Cookie 大小限制在 4kb 左右(不同的瀏覽器有一些區別),對于一些復雜的業務場景可能不夠
這兩個缺點在 Localstorage 中得到了有效的解決,下面我們就開始學習 Localstorage。
2. 兼容性
截止目前為止,已經有大部分瀏覽器已經支持 Localstorage,包括 IE8。
具體瀏覽器是否支持 Localstorage 可以通過簡單的 JavaScript 代碼判斷。
function testLocalstorage(){
if ( typeof window.localStorage == "object" ) return true;//判斷localstorage對象是否定義
else return false;//未定義返回false
}
3. API 接口
Localstorage 是一個簡單的 key/value 形式的數據庫,以鍵值對的方式存儲,所以提供的接口主要是基于 k/v 的操作?;谔峁┑慕涌谥荒艽鎯唵蔚囊痪S數組,但是有些業務場景可能會牽涉到多維數據甚至對象的存儲,怎么辦?
- 建議使用
JSON.stringify()
將數據轉化成字符串方式再存儲; - 使用復雜的前端數據庫,例如 indexDB,具體不做深入討論。
3.1 存儲數據
window.localStorage.setItem("test",1)//設置key=test的值為1
localStorage.setItem("test",1)//設置key=test的值為1,localstorage可以作為全局對象處理
localStorage.test = 1//可以通過屬性值的方式直接操作localstorage的key
運行下面案例代碼,試一試:
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
window.localStorage.setItem("test",1)//設置key=test的值為1
localStorage.setItem("test",1)//設置key=test的值為1,localstorage可以作為全局對象處理
localStorage.test = 1//可以通過屬性值的方式直接操作localstorage的key
document.getElementById("demo").innerHTML =
"localStorage.test 的值是" + localStorage.test + "。";
</script>
</body>
</html>
3.2 讀取數據-按鍵值
getItem
var a = window.localStorage.getItem("test")//獲取key=test的值
var a = localStorage.test//可以直接通過對象屬性的方式操作
如果獲取一個不存在的 key 返回 null ,下同。
3.3 讀取數據-按位置
var a = window.localStorage.key(0)//可以根據key在localstorage的位置的方式操作,類似操作JavaScript的array的方式
3.4 刪除數據
window.localStorage.removeItem("test")//刪除key=test的值
window.localStorage.test = ''//可以通過賦空值的方式等價操作
3.5 整體清空
3.6 存儲事件監聽
當 localstorage 發生改變時,可以通過監聽 storage 事件作出相應的業務處理。
if (window.addEventListener) { //通過addEventListener方式監聽事件,為了兼容IE
window.addEventListener("storage", function(e){//監聽storage事件
//業務處理
}, false);
} else {
window.attachEvent("onstorage", function(e){//通過attachEvent方式監聽事件
//業務處理
});
}
4. 適用場景及局限性
4.1 局限性
前邊提到 Localstorage 相比較 Cookie 的優勢是容量大和節省 HTTP 帶寬,但是它還是有自身的缺點,下邊羅列了它的缺點
- 5M 容量依然小,用過數據庫的同學應該知道,MySQL 隨便一個表加上索引很容易超過 5M
- 不能跨域名訪問,同一個網站可能會牽涉到子域名
- 不能存儲關系型數據
- 不能搜索
4.2 適用場景
那么以上缺點有沒有解決方案,肯定是有的,例如 HTML 的 webSql 或者 indexDB,那肯定有人問了,為什么不直接用最復雜的數據庫,跳過 Localstorage 呢?原因是技術沒有最好的,只有最適合的,不同的業務場景應該選擇最匹配的而且成本最小的解決方案。例如你在存儲簡單的業務場景中的臨時數據時完全可以使用 Localstorage 甚至 Cookie 搞定,假如使用 indexDB 的話系統的開發成本以及維護成本會翻番,得不償失。
所以說總結下來 Localstorage 的適用業務場景是:
- 數據關系簡單明了
- 數據量小
- 數據無需持久化存儲且不需要考慮安全性
- 無需跟服務器交互
5. 業務實戰
5.1 項目使用場景
之前開發一個場館管理系統時有一個功能是根據用戶輸入的關鍵字搜索場館,業務方的需求是需要臨時保留搜索關鍵詞的歷史記錄,考慮到是臨時保存,而且只保存關鍵字不需要復雜的數據結構存儲且只保存 10 條最新的數據,項目組商量下來決定使用 Localstorage 保存,搜索成功之后添加到歷史記錄。
function chooseClubItem(e) {
let mid = e.currentTarget.dataset.id
let findAddressInfo = this.data.markers.find(item => item.id === mid)
const historyList = window.localStorage.getItem('historyList') || []//獲取localstorage需要操作的鍵值
if (findAddressInfo) {
const index = historyList.findIndex(history => history.id == findAddressInfo.id)
if (index !== -1) {
historyList.splice(index, 1)
}
if(historyList.length>=10)historyList.pop();//超過最大歷史數目,刪除最后一個
historyList.unshift(findAddressInfo)//加入到歷史存儲隊列中
window.localStorage.setItem('historyList', historyList)//設置離線存儲
}
},
清空歷史記錄
function delHistory() {
let that = this
showModal({//彈出確認對話框
title: '',
content: '您確定要清空搜索歷史嗎',
showCancel: true,
cancelText: '取消',
cancelColor: '#000000',
confirmText: '確定',
confirmColor: '#3CC51F',
success: result => {
if (result.confirm) {
window.localStorage.removeItem("historyList")//情況歷史隊列
}
}
})
},
5.2 使用第三方庫
現實中考慮到瀏覽器對 Localstorage 畢竟不是百分之百兼容,而且 Localstorage 本身提供的 API 比較簡單,所以實際項目中可以考慮使用第三方封裝庫操作,比如 store.js。
store.js 優先選擇 localStorage 來進行存儲,在 IE6 和 IE7 下降級使用 userData 來達到目的。 沒有使用 flash ,不會減慢你的頁面加載速度。也沒有使用 Cookies ,不會使你的網絡請求變得臃腫。store.js 依賴 JSON 來序列化數據進行存儲。
6. 總結
以上介紹了 Localstorage 和傳統離線存儲的優缺點對比,Localstorage 的使用方法以及項目實戰分析??偟膩碚f Localstorage 適用于業務簡單的輕量級存儲中,通過簡單的 API 操作增刪改查存儲鍵值對,而且可以通過事件監聽的方式獲取 Localstorage 的操作事件,無需發送 HTTP 請求,真正實現了離線存儲