HTML5 5大儲存方式總結
總體情況
h5之前,儲存主要是用cookies。cookies缺點有在請求頭上帶著資料,大小是4k之內。主Domain汙染。
主要應用:購物車、客戶登入
對於IE瀏覽器有UserData,大小是64k,只有IE瀏覽器支援
目標
-
解決4k的大小問題
-
解決請求頭常帶儲存資訊的問題
-
解決關係型儲存的問題
-
跨瀏覽器
1.本地儲存localstorage
儲存方式:
以鍵值對(Key-Value)的方式儲存,永久儲存,永不失效,除非手動刪除。
大小:
每個域名5M
支援情況:
注意:IE9 localStorage不支援本地檔案,需要將專案署到伺服器,才可以支援!
檢測方法:
if(window.localStorage){
alert('This browser supports localStorage');
}else{
alert('This browser does NOT support localStorage');
}
常用的API:
getItem //取記錄
setIten//設定記錄
removeItem//移除記錄
key//取key所對應的值
clear//清除記錄
儲存的內容:
陣列,圖片,json,樣式,指令碼。。。(只要是能序列化成字串的內容都可以儲存)
2.本地儲存sessionstorage
HTML5 的本地儲存 API 中的 localStorage 與 sessionStorage 在使用方法上是相同的,區別在於 sessionStorage 在關閉頁面後即被清空,而 localStorage 則會一直儲存。
3.離線快取(application cache)
本地快取應用所需的檔案
使用方法:
①配置manifest檔案
頁面上:
<!DOCTYPE HTML>
<html manifest="demo.appcache">
...
</html>
Manifest 檔案:
manifest 檔案是簡單的文字檔案,它告知瀏覽器被快取的內容(以及不快取的內容)。
manifest 檔案可分為三個部分:
①CACHE MANIFEST - 在此標題下列出的檔案將在首次下載後進行快取
②NETWORK - 在此標題下列出的檔案需要與伺服器的連線,且不會被快取
③FALLBACK - 在此標題下列出的檔案規定當頁面無法訪問時的回退頁面(比如 404 頁面)
完整demo:
CACHE MANIFEST
# 2016-07-24 v1.0.0
/theme.css
/main.js
NETWORK:
login.jsp
FALLBACK:
/html/ /offline.html
伺服器上:manifest檔案需要配置正確的MIME-type,即 “text/cache-manifest”。
如Tomcat:
<mime-mapping>
<extension>manifest</extension>
<mime-type>text/cache-manifest</mime-type>
</mime-mapping>
常用API:
核心是applicationCache物件,有個status屬性,表示應用快取的當前狀態:
0(UNCACHED) : 無快取, 即沒有與頁面相關的應用快取
1(IDLE) : 閒置,即應用快取未得到更新
2 (CHECKING) : 檢查中,即正在下載描述檔案並檢查更新
3 (DOWNLOADING) : 下載中,即應用快取正在下載描述檔案中指定的資源
4 (UPDATEREADY) : 更新完成,所有資源都已下載完畢
5 (IDLE) : 廢棄,即應用快取的描述檔案已經不存在了,因此頁面無法再訪問應用快取
相關的事件:
表示應用快取狀態的改變:
checking : 在瀏覽器為應用快取查詢更新時觸發
error : 在檢查更新或下載資源期間傳送錯誤時觸發
noupdate : 在檢查描述檔案發現檔案無變化時觸發
downloading : 在開始下載應用快取資源時觸發
progress:在檔案下載應用快取的過程中持續不斷地下載地觸發
updateready : 在頁面新的應用快取下載完畢觸發
cached : 在應用快取完整可用時觸發
Application Cache的三個優勢:
① 離線瀏覽
② 提升頁面載入速度
③ 降低伺服器壓力
注意事項:
1. 瀏覽器對快取資料的容量限制可能不太一樣(某些瀏覽器設定的限制是每個站點 5MB)
2. 如果manifest檔案,或者內部列舉的某一個檔案不能正常下載,整個更新過程將視為失敗,瀏覽器繼續全部使用老的快取
3. 引用manifest的html必須與manifest檔案同源,在同一個域下
4. 瀏覽器會自動快取引用manifest檔案的HTML檔案,這就導致如果改了HTML內容,也需要更新版本才能做到更新。
5. manifest檔案中CACHE則與NETWORK,FALLBACK的位置順序沒有關係,如果是隱式宣告需要在最前面
6. FALLBACK中的資源必須和manifest檔案同源
7. 更新完版本後,必須重新整理一次才會啟動新版本(會出現重刷一次頁面的情況),需要新增監聽版本事件。
8. 站點中的其他頁面即使沒有設定manifest屬性,請求的資源如果在快取中也從快取中訪問
9. 當manifest檔案發生改變時,資源請求本身也會觸發更新
離線快取與傳統瀏覽器快取區別:
1. 離線快取是針對整個應用,瀏覽器快取是單個檔案
2. 離線快取斷網了還是可以開啟頁面,瀏覽器快取不行
3. 離線快取可以主動通知瀏覽器更新資源
4.Web SQL
關係資料庫,通過SQL語句訪問
Web SQL 資料庫 API 並不是 HTML5 規範的一部分,但是它是一個獨立的規範,引入了一組使用 SQL 操作客戶端資料庫的 APIs。
支援情況:
Web SQL 資料庫可以在最新版的 Safari, Chrome 和 Opera 瀏覽器中工作。
核心方法:
①openDatabase:這個方法使用現有的資料庫或者新建的資料庫建立一個數據庫物件。
②transaction:這個方法讓我們能夠控制一個事務,以及基於這種情況執行提交或者回滾。
③executeSql:這個方法用於執行實際的 SQL 查詢。
開啟資料庫:
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024,fn);
//openDatabase() 方法對應的五個引數分別為:資料庫名稱、版本號、描述文字、資料庫大小、建立回撥
執行查詢操作:
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS WIN (id unique, name)');
});
插入資料:
var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS WIN (id unique, name)');
tx.executeSql('INSERT INTO WIN (id, name) VALUES (1, "winty")');
tx.executeSql('INSERT INTO WIN (id, name) VALUES (2, "LuckyWinty")');
});
讀取資料:
db.transaction(function (tx) {
tx.executeSql('SELECT * FROM WIN', [], function (tx, results) {
var len = results.rows.length, i;
msg = "<p>查詢記錄條數: " + len + "</p>";
document.querySelector('#status').innerHTML += msg;
for (i = 0; i < len; i++){
alert(results.rows.item(i).name );
}
}, null);
});
由這些操作可以看出,基本上都是用SQL語句進行資料庫的相關操作,如果你會MySQL的話,這個應該比較容易用。
5.IndexedDB
索引資料庫 (IndexedDB) API(作為 HTML5 的一部分)對建立具有豐富本地儲存資料的資料密集型的離線 HTML5 Web 應用程式很有用。
同時它還有助於本地快取資料,使傳統線上 Web 應用程式(比如移動 Web 應用程式)能夠更快地執行和響應。
非同步API:
在IndexedDB大部分操作並不是我們常用的呼叫方法,返回結果的模式,而是請求——響應的模式,比如開啟資料庫的操作
這樣,我們開啟資料庫的時候,實質上返回了一個DB物件,而這個物件就在result中。
由上圖可以看出,除了result之外。還有幾個重要的屬性就是onerror、onsuccess、onupgradeneeded(我們請求開啟的資料庫的版本號和已經存在的資料庫版本號不一致的時候呼叫)。
這就類似於我們的ajax請求那樣。我們發起了這個請求之後並不能確定它什麼時候才請求成功,所以需要在回撥中處理一些邏輯。
關閉與刪除:
function closeDB(db){
db.close();
}function deleteDB(name){
indexedDB.deleteDatabase(name);
}
資料儲存:
indexedDB中沒有表的概念,而是objectStore,一個數據庫中可以包含多個objectStore,objectStore是一個靈活的資料結構,可以存放多種型別資料。
也就是說一個objectStore相當於一張表,裡面儲存的每條資料和一個鍵相關聯。
我們可以使用每條記錄中的某個指定欄位作為鍵值(keyPath),也可以使用自動生成的遞增數字作為鍵值(keyGenerator),也可以不指定。
選擇鍵的型別不同,objectStore可以儲存的資料結構也有差異。