瀏覽器存儲及使用

伴隨着WEB的發展,瀏覽器的存儲方式及技術不斷的發生更改,從剛開始的cookie,到localstorage,sessionStorage,再到IndexedDB,再到如今的Web SQL,做爲一名合格的前端開發,固然須要對這些技術瞭如指掌並熟練掌握,本文將比較全面的介紹常見的瀏覽器存儲以及其使用。javascript

1.Cookie

Cookie是一個用戶經過瀏覽器瀏覽網站產出的信息的票根,Cookies一般被用來標示一個網站用戶的瀏覽經歷,它可能包含這個用戶的我的偏好或訪問這個網站的一些輸入信息。用戶能夠本身隨意操做他們瀏覽器中的Cookie。
Cookies 能夠經過服務端使用 Set-Cookie Http header來設置和修改,固然也可使用javascript的document.cookie去操做。html

瀏覽器兼容性

Cookie兼容性
詳細請參考 http://caniuse.com/#search=cookie前端

在瀏覽器中操做以下:

//讀取網站下全部的cookie信息,獲取的結果是一個以分號;做爲分割的一個字符串
var allCookies = document.cookie;
//例如:在百度首頁,獲取的以下
// "BAIDUID=B32F2BF6BCB66D5559E199F5B1908F4C:FG=1; PSTM=1444711125; BIDUPSID=9DE77BD4B191F421CA54DB11C954067A; ispeed_lsm=0; MCITY=-289%3A; BDSFRCVID=hWtsJeC62Ag8XZc4Nvqo2MixJD2vkWoTH6aoB7vKuwGS_LREoJS6EG0PtvlQpYD-KiV2ogKK0eOTHvvP; H_BDCLCKID_SF=JbADoDD-JCvbfP0kKtr_MJQH-UnLq-vUbT7Z0l8KtqjJbMnL-TOF5R_eD4c0hUTRtjcW-b7mWIQHDp_65xRh5U-9BPvN04RZLbc4KKJxbPQSVtJXQKcvMq5XhUJiB5O-Ban7LtQxfJOKHICRe5-ajxK; BD_CK_SAM=1; locale=zh; BD_HOME=0; H_PS_PSSID=1455_18241_18559_17000_15227_11651; BD_UPN=123253"

//往原來的已經存在的cookie中加入新的cookie
document.cookie ="test=yui";

//固然也能夠在後面加上可選擇的選項鍵值對,例如domain,以及其餘path,expires
document.cookie="test=yui;domain=.baidu.com"

//刪除cookie,就是讓這個cookie值得expires過,就是設置這個expires爲0
document.cookie="test=yui;domain=.baidu.com;expires=0");

須要注意的地方:

1.經過上面的代碼,能夠看到document.cookie是個可訪問的屬性,可是它有內置的setter和getter的function,而不是一個簡單的字符串數據,你的get和set都會調用這些原生內置的函數。html5

2.cookie支持跨域,能夠經過在根域名設置cookie,共享多個子域名的數據。java

Cookie的Chrome瀏覽器實現

cookie解析: https://code.google.com/p/chromium/codesearch#chromium/src/net/cookies/parsed_cookie.hnode

2.Web Storage

Web Storage有兩種機制,分別爲sessionStorage和localStorage。
sessionStorage用於本地存儲一個會話(session)中的數據,這些數據只有在同一個會話中的頁面才能訪問而且當會話結束後數據也隨之銷燬。所以sessionStorage是一種半持久化的本地存儲(會話級別的存儲),而localStorage用於持久化的本地存儲,除非主動刪除數據,不然數據是永遠不會過時的。web

這兩個對象,對外的方法主要有: setItem,getItem,以鍵值對的形式存儲和讀取,key按照索引獲取當前存儲的key值,找不到時返回null,length屬性表明當前存儲的key,value對數chrome

瀏覽器兼容性

Web Storage瀏覽器兼容性
詳細請參考: http://caniuse.com/#search=localstorage數據庫

代碼示例(以localStorage爲例)

var username = 'helloworld';
var storageUsername;
var randomArr = [Math.random(),Math.random(),Math.random(),Math.random()];
var storageRandomArr;

//storage username,key值區分大小寫,存入的內容爲這個變量調用toString方法的結果
localStorage.setItem("username",username);

//獲取
storageUserName  = localstorage.getItem("username");
//"helloworld"

//刪除
localStorage.removeItem("username");

storageUserName  =  localstorage.getItem("username");
// null

//存儲對象時,能夠先調用JSON.stringify方法,而後取出的時候再調用JSON.parse方法獲取結果
localStorage.setItem("randomarr",JSON.stringify(randomArrr));
storageRandomArr = JSON.parse(localStorage.getItem("randomarr"));

Object.prototype.toString.call(storageRandomArr);
// "object Array"

3.IndexDB

IndexedDB 是一個爲了可以在客戶端存儲可觀數量的結構化數據,而且在這些數據上使用索引進行高性能檢索的 API。編程

IndexedDB 分別爲同步和異步訪問提供了單獨的 API ,異步 API 方法調用完後會當即返回,而不會阻塞調用線程。

要異步訪問數據庫,要調用 window 對象 indexedDB 屬性的 open() 方法。該方法返回一個 IDBRequest 對象 (IDBOpenDBRequest);異步操做經過在 IDBRequest 對象上觸發事件來和調用程序進行通訊。

IndexDb是NoSQL數據庫,是一種支持事務的瀏覽器數據庫,基本操做就是,打開數據庫,增刪改查各類。

瀏覽器兼容性

IndexDB兼容性
詳細請參考: http://caniuse.com/#search=IndexDB

代碼示例 - 1.打開數據庫

//處理瀏覽器兼容性
window.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB;

//若是該數據庫MyDatabase不存在,則會被建立;若是已經存在,則被打開。
var request = window.indexedDB.open("MyDatabase");

//打開數據庫失敗的回調
request.onerror = function(event) {
  console.log("failure");
};
//代開數據成功的回調
request.onsuccess = function(event) {
  console.log("success");
};

代碼示例 - 2.初始化數據庫

var dbName = "MyDatabase";
var dbVersion = 2;//整數
// open函數接受的第二個參數,表明數據的版本,當打開的版本號比當前的版本號大時,會觸發onupgradeneeded這個回調
var request = window.indexedDB.open(dbName,dbVersion);
var studentsData = [{
    id:"001",name:"xiaoming",email:0
},{
    id:"002",name:"xiaoxiang",email:1
}];
var tableName = 'students';

request.onerror = function (event) {
    //錯誤處理
};

request.onupgradeneeded = function (event) {
    var db = event.target.result;
    //建立表,以id字段做爲主鍵來確保惟一,使用keyPath表示
    var objectStore = db.createObjectStore(tableName, { keyPath: "id" });

    //給表添加索引
    objectStore.createIndex("name","name",{unique:false});//非unique索引
    objectStore.createIndex("email","email",{unique:true});//email字段做爲unique索引

    for(var i in studentsData){
        //插入數據
        objectStore.add(studentsData[i]);
    }

    console.log("---init db success---");
}

代碼示例 - 3.使用事務添加、刪除數據

transaction() 方法接受兩個參數並返回一個事務對象。第一個參數是事務但願跨越的對象存儲空間的列表,即數據庫中的表名稱。若是你但願事務可以跨越全部的對象存儲空間你能夠傳入一個空數組。第二個參數若是你沒有爲第二個參數指定任何內容,默認只讀。

事務方法接受參數

插入學生003,004,005

var dbName = "MyDatabase";
var request = window.indexedDB.open(dbName);
var addData = [{
    id:"003",name:"xiaofang1",email:"3@qq.com"
},{
    id:"004",name:"xiaofang2",email:"4@qq.com"
},{
    id:"005",name:"xiaofang3",email:"5@qq.com"
}];
var tableName = 'students';

//打開數據庫失敗的回調
request.onerror = function(event) {
    console.log("open indexDb database failure");
};
//代開數據成功的回調
request.onsuccess = function(event) {
    var db = event.target.result;
    var transaction = db.transaction([tableName],'readwrite');
    var objectStore;
    var i;

    //事務主要有三個回調,error,abort,success
    transaction.onerror = function (event) {
        //處理錯誤
        console.log(event);
    }
    transaction.onbort = function () {
        //事務中斷處理
    }
    transaction.oncomplete = function () {
        console.log("添加數據成功");
    }

    objectStore  = transaction.objectStore(tableName);

    for(i  in addData){
        var request = objectStore.add(addData[i]);

        request.onsuccess = function (event) {
            console.log("add one success");
        }
    }
};

刪除001學生

var dbName = "MyDatabase";
var request = window.indexedDB.open(dbName);
var db;
var tableName = 'students';

request.onerror = function () {
};

request.onsuccess  = function (event) {
    var objectStore;
    var transaction;

    db =  event.target.result;
    transaction= db.transaction([tableName],'readwrite');
    transaction.onerror = function (event) {
        //處理錯誤
        console.log("error when delete 001 "+ event.target.errorCode);
    }
    transaction.onbort = function () {
        //事務中斷處理
    }
    transaction.oncomplete = function () {
        console.log("刪除學生001成功");
    }
    objectStore = transaction.objectStore(tableName);
    objectStore.delete("001");
};

代碼示例 - 4.使用索引查找數據

主要調用IDBObjectStore示例對象的index方法

var dbName = "MyDatabase";
var request = window.indexedDB.open(dbName);
var db;
var tableName = 'students';

request.onerror = function () {
};

request.onsuccess  = function (event) {
    var index;
    var objectStore;

    db =  event.target.result;
    objectStore = db.transaction([tableName]).objectStore(tableName);
    //根據索引字段email朝找3@qq.com的學生
    index = objectStore.index("email").get("3@qq.com");
    index.onsuccess = function(event) {
        console.log(event.target.result);
    };
    index.onerror = function (event) {
        console.log("error when find  by index "+ event.target.errorCode);
    }
};

indexDb還有遊標查找功能,限於篇幅,就不展開介紹了

4.WebSql

Web SQL Database API實際上未包含在HTML 5規範之中,它是一個獨立的規範,它引入了一套使用SQL操做客戶端數據庫的API,這些API有同步的,也有異步的,通常狀況下,都會使用異步API。它的核心方法有三個:openDatabase,transaction和executeSql。這些API已經被普遍的實如今了不一樣的瀏覽器裏,尤爲是手機端瀏覽器。雖然W3C官方在2011年11月聲明已經再也不維護Web SQL Database規範,但因爲其普遍的實現程度,瞭解這些API對 Web開發仍是很是有必要的。

瀏覽器兼容性

WebSql瀏覽器兼容性
詳情請參考

代碼示例

var db; 
var info = {
    dbName :"MyDataBase",//數據庫名稱
    dbVersion:"0.1",//版本
    dbDisplayName:"測試數據庫",//顯示名稱
    dbEstimatedSize:10*1024*1024 //數據庫大小,單位字節
};

db = window.openDatabase(info.dbName,info.dbVersion,info.dbDisplayName,info.dbEstimatedSize);

//初始化students表
db.transaction(function (trans) {
    //執行Sql,若是students表不存在,則建立改表
    trans.executeSql("create table if not exists students(id unique,name text null,email text null)",[], function () {
        console.log("init success");
    }, function () {
        console.log("error happen");
    });
});


//插入數據
db.transaction(function (trans) {
    trans.executeSql("insert into students(name,email) values(?,?)",['xiaoming','1@qq.com'], function () {
        console.log("insert ok 1");
    }, function () {
        console.log(arguments);
    });
    trans.executeSql("insert into students(name,email) values(?,?)",['xiaohong','2@qq.com'],function () {
        console.log("insert ok 2");
    }, function () {
        console.log(arguments);
    });
});

//刪除數據
db.transaction(function (trans) {
   trans.executeSql("delete from students where name = ? ",['xiaohong'], function (trans,result) {
       console.log("delete success");
   }, function (trans,message) {
       console.log("error happen");
   });
});

//查詢數據
db.transaction(function (trans) {
    trans.executeSql("select * from students",[], function (trans,result) {
        console.log("總共查詢到 "+result.rows.length+" 條數據");
    }, function (trans,message) {
        console.log("error happen");
    });
});

5.其餘

Application Cache

Application Cache翻譯成中文爲應用程序緩存,是html5中爲實現離線瀏覽所提供的API。結合Manifest文件使用,使用編程方式,更新瀏覽器緩存內容。主要調用update與swapCache去更新瀏覽緩存,目前該技術已經被最新的規範所廢棄,轉而使用了Service Workers。

Service Workers

一個 service worker 是一段運行在瀏覽器後臺進程裏的腳本,它獨立於當前頁面,提供了一些不須要與web頁面交互的功能,即那種在網頁背後悄悄執行的能力。在未來,基於它能夠實現消息推送,靜默更新等服務,可是目前它首先要具有的功能是攔截和處理網絡請求,包括可編程的響應緩存管理。

小結

目前Cookie的兼容性最好,使用的最普遍,但有被濫用的趨勢。Web Storage 兼容比較好,除了老闆的IE 6,7不支持外,其餘主流瀏覽器都已經支持了,使用起來也方便簡單,適合存儲鍵值對數據。WebSql因爲未在HTML5規範中,前景堪憂,適當瞭解下。IndexDb目前來看,兼容性不太好,可是前景很好,目前由w3c在推廣,相信在之後應該有個大爆發(我的見解)。
Application Cache目前已經被廢棄,Service Workers目前屬於起步階段,感受離實用還須要時間。

參考連接

caniuse
Cookie
谷歌開發者中心文檔
Mozilia 開發者中心
Service Workers

【做者信息】葉文兵,本科畢業於安徽師範大學,入坑前端開發快3年,普通頁面仔一枚。現任MaxLeap UX組開發人員,負責公司主要項目前端開發工做,逐漸往nodejs全棧方向發展。
歡迎查看原文博客:https://blog.maxleap.cn/archives/555

歡迎關注微信訂閱號:從移動到雲端

相關文章
相關標籤/搜索