html5離線存儲
STORAGE(存儲)
Cookie
在HTML5以前我們會使用 cookie,在瀏覽器端緩存一些數據,例如:登錄用戶信息,歷史搜索信息等等。但是cookie所支持的容量僅僅只有 4k ,也沒有專門的api來操作,只能依賴一些開源的庫, 這里使用 cookies.js 存儲和獲取cookie信息
// 這是一個cookie值
Cookies.set('key', 'value');
// 鏈式調用
Cookies.set('key', 'value').set('hello', 'world');
// 可以額外設置一些參數
Cookies.set('key', 'value', { domain: 'www.example.com', secure: true });
// 設置緩存時間
Cookies.set('key', 'value', { expires: 600 }); // Expires in 10 minutes
Cookies.set('key', 'value', { expires: '01/01/2012' });
Cookies.set('key', 'value', { expires: new Date(2012, 0, 1) });
Cookies.set('key', 'value', { expires: Infinity });
// 獲取
Cookies.get('key');
由此可見用cookie存儲有一下幾個缺點:
存儲數據的量比較小
本身沒有方便的api對其進行操作
cookie信息會在http請求時加入到請求頭中,既不安全也增加了帶寬。
WEB Storage
HTML5 提拱更好的本地存儲規范 localStorage 和 sessionStorage , 它們將數據存儲在本地,而且在http請求時不會攜帶 Storage 里的信息, 使用方式也很簡單:
localStorage.setItem('key', 'value');
localStorage.getItem('key');
localStorage.removeItem('key');
sessionStorage.setItem('key', 'value');
sessionStorage.getItem('key');
sessionStorage.removeItem('key');
sessionStorage 和 localStorage 使用方式及特性基本一致,唯一的區別是, sessionStorage 只在會話內有效,當瀏覽器窗口關閉,sessionStorage 緩存的數據會自動被清除, 而 localStorage 只要不手動清除,它會永久保存在本地。
這里有張圖片分析了 cookie 、 localStorage 、 sessionStorage 三者的區別
OFFLINE(離線)
為了讓 webapp 擁有像 native app 一樣的功能和體驗, 在 HTML5的規范中加入了許多新的api, 讓頁面可以在離線環境下正常訪問。 service worker 和 indexedDB 兩者配合可以就可以開發離線使用的 webapp 了,由于 service worker 目前的兼容性不太好,這里我們寫介紹下比較早的方案 application cache 。
service worker
Service Worker是基于Web Worker的事件驅動的,他們執行的機制都是新開一個線程去處理一些額外的,以前不能直接處理的任務。對于Web Worker,我們可以使用它來進行復雜的計算,因為它并不阻塞瀏覽器主線程的渲染。而Service Worker,我們可以用它來進行本地緩存,相當于一個本地的proxy。說起緩存,我們會想起我們常用的一些緩存技術來緩存我們的靜態資源,但是老的方式是不支持調試的,靈活性不高。使用Service Worker來進行緩存,我們可以用javascript代碼來攔截瀏覽器的http請求,并設置緩存的文件,直接返回,不經過web服務器,然后,做更多你想做的事情。
因此,我們可以開發基于瀏覽器的離線應用。這使得我們的web應用減少對網絡的依賴。例如,我們開發了一個新聞閱讀的web應用,當你用手機瀏覽器在有網絡的情況下打開時,你可以正常的獲取新聞內容。可是,如果手機進入飛行模式,那這個應用你就沒法使用了。
如果我們使用了Service Worker做緩存,瀏覽器http請求會先經過Service Worker,通過url mapping去匹配,如果匹配到了,則使用緩存數據,如果匹配失敗,則繼續執行你指定的動作。一般情況下,匹配失敗則讓頁面顯示“網頁無法打開”。
service work 生命周期
service work demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script>
navigator.serviceWorker.register("/service-worker.js").then(function(serviceWorker) {
console.log("success!");
});
</script>
</head>
<body>
</body>
</html>
在頁面注冊service-worker成功時就會調用這個js
this.oninstall = function(e) {
var resources = new Cache();
var visited = new Cache();
// Fetch them.
e.waitUntil(resources.add(
"/index.html",
"/fallback.html",
"/css/base.css",
"/js/app.js",
"/img/logo.png"
).then(function() {
// Add caches to the global caches.
return Promise.all([
caches.set("v1", resources),
caches.set("visited", visited)
]);
}));
};
this.onfetch = function(e) {
e.respondWith(
// Check to see if request is found in cache
caches.match(e.request).catch(function() {
// It's not? Prime the cache and return the response.
return caches.get("visited").then(function(visited) {
return fetch(e.request).then(function(response) {
visited.put(e.request, response);
// Don't bother waiting, respond already.
return response;
});
});
}).catch(function() {
// Connection is down? Simply fallback to a pre-cached page.
return caches.match("/fallback.html");
});
);
};
service worker 采用事件監聽機制, 上面的代碼監聽了 install 和 fetch 事件,當 server worker 安裝成功后,調用此方法,然后緩存頁面的資源文件, fetch 頁面請求事件, server worker 攔截到用戶請求,當發現請求文件命中緩存則從緩存中取得文件,返回給頁面,無需經過服務器,借此達到離線的目的。
當然 service worker 的功能遠不止現在這些
indexedDB
indexedDB 是一個用于本地存儲數據的 nosql 數據庫,擁有極快的數據查詢速度,而且可以直接保存js 對象。相比web sql(sqlite)更加高效,包括索引、事務處理和健壯的查詢功能。indexedDB特點:
1.一個網站可能有一個或多個 IndexedDB 數據庫,每個數據庫必須具有惟一的名稱。
2.一個數據庫可包含一個或多個對象存儲
一個對象存儲(由一個名稱惟一標識)是一個記錄集合。每個記錄有一個鍵 和一個值。該值是一個對象,可擁有一個或多個屬性。鍵可能基于某個鍵生成器,從一個鍵路徑衍生出來,或者是顯式設置。一個鍵生成器自動生成惟一的連續正整數。鍵路徑定義了鍵值的路徑。它可以是單個 JavaScript 標識符或多個由句點分隔的標識符。
基本使用方式如下:
var openRequest = indexedDB.open("auto_people", 3);
var db; //數據庫對象
openRequest.onupgradeneeded = function(e){
console.log("Running onupgradeeded...");
var thisDB = e.target.result;
if(!thisDB.objectStoreNames.contains("people")){
thisDB.createObjectStore("people", {autoIncrement:true}); //新建一個store并設置主鍵自增長
}
}
//創建成功
openRequest.onsuccess = function(e){
console.log("success!");
db = e.target.result;
//Listen for add clicks
}
openRequest.onerror = function(e){
console.log("error!");
console.dir(e);
}
//這應該站在別的地方處理,這是做一個代碼展示
var transaction = db.transaction(['people'], "readwrite"); //創建一個連接
var store = transaction.objectStore("people"); //獲取store
var request = store.add({
name: 'myron',
email: 'test@qq.com',
created: new Date()
}); //添加信息
request.onerror = function(e){
alert('error!');
console.dir(e);
} //當添加失敗時調用
request.onsuccess = function(e){
console.log('Did it!');
} //添加成功時調用
request = store.get(1); //獲取第一條數據
request.onsuccess = function(e){
var result = e.target.result;
console.dir(result);
if(result){
//拿到存儲的對象
}
}
application cache
來自:http://www.html5cn.org/article-9789-1.html