客戶端儲存筆記

三千煩惱絲發表於2017-04-26

之前學些東西遇到的一個例子遇到客戶端儲存,圖靈也正好有這本,索性買下來,今天發現js高程3裡面也有講這些東西,而且更為詳細一些,相互參照,記錄下來。
主要的4種方式

1 cookie 繫結在特定域名下。同一個域不同瀏覽器限制數量

cookie構成 1.名稱(不區分大小寫,建議區分)2. 值 3. 域 4. 路徑 5. 失效時間(GMT格式(Wdy,DD-Mon-YYYY HH:MM:SS GMT))6. 安全標誌

示例

document.cookie = "nameOfCookie=value"; 名稱與值
document.cookie = "name=Raymond";
document.cookie = "name=Raymond; expires=Fri, 31 Dec 9999 23:59:59 GMT";包含過期時間
document.cookie = "name=Raymond;domain=app.foo.com";包含域名
document.cookie = "name=Raymond;domain=app.foo.com";path=/; secure  包含安全標誌和域路徑  

各個名值對用分號分隔 js處理 編碼解碼

document.cookie = encodeURIComponent("name") + "=" + encodeURIComponent("value");  

第3方庫來處理cookie
< MDN連結>= https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie

getItem:獲取 Cookie  
setItem:設定 Cookie(包括有效期、路徑、域名,等等)  
removeItem:刪除 Cookie  
hasItem:檢查 Cookie 是否存在
keys:返回所有 Cookie 的名稱  

2. WEB儲存

Web 儲存的兩個版本:本地儲存(Local Storage)和會話儲存(Session Storage)。兩者使用完全相同的 API,本地儲存會持久存在(或者直到使用者清除),會話儲存只要瀏覽器關閉就會消失。 限制前者每個源5MB限制 Chrome和Safari限制大小為2.5MB ios版safari和android版webkit 限制為2.5MB

 localStorage.setItem:設定特定鍵的值
 localStorage.getItem:檢索特定鍵的值
 localStorage.removeItem:刪除鍵及與其關聯的值
 localStorage.clear:刪除所有的鍵 / 值對(但只限於發出請求的特定域名)
 localStorage.key();  獲取鍵

Session Storage 可以結合length屬性和key()來迭代取值

 for (var i=0, len = sessionStorage.length; i < len; i++){
     var key = sessionStorage.key(i);
     var value = sessionStorage.getItem(key);
         alert(key + "=" + value);
    }  

也可用for-in來迭代

 for (var key in sessionStorage){
    var value = sessionStorage.getItem(key);
    alert(key + "=" + value);
 }  

可以使用delete操作符刪除物件屬性 也可用 removeItem()
storage儲存事件
1. domain :域名變化 2. key :設定刪除或儲存 3. newvalue: 4.oldvalue 5. url : 頁面url
6. storageArea : 被修改的 storage 物件

window.addEventListener('storage',function(e){
      console.log('key='+e.key+',oldValue='+e.oldValue+',newValue='+e.newValue);
  })

Local Storage 的優點

相比於Cookies:其提供了更直觀地介面來儲存資料,更安全,能儲存更多資料
Local Storage 的缺點

只能儲存字串資料(直接儲存複合資料型別如陣列/物件等,都會轉化成字串,會存在存取資料不一致的情況):

3 IndexedDB 非同步結構化儲存

Firefox 4+上限每個源50MB,Chrome限制50MB,移動裝置Firefox 4最多允許5MB。Firefox不允許訪問本地檔案訪問IndexedDB,Chrome瀏覽器不限制。 瀏覽器支援檢測

 function idbOK() {
     return "indexedDB" in window &&
    !/iPad|iPhone|iPod/.test(navigator.platform); 移動平臺支援檢測
 }  

開啟資料庫

var openrequest, db;
var openRequest = indexedDB.open("ora_idb1",1);

openRequest.onupgradeneeded = function(e) {
    console.log("running onupgradeneeded");
}
openRequest.onsuccess = function(e) {
    console.log("running onsuccess");
    db = e.target.result;
}
openRequest.onerror = function(e) {
    console.log("onerror!");
    console.dir(e);
}  

關閉資料庫

var openrequest = indexedDB.open('ora_idb1', 2);
 // ...
openrequest.onsuccess = function(e){
console.log('連線資料庫成功');
var db = e.target.result;
db.close();
console.log('資料庫已關閉');
}  

刪除資料庫

indexedDB.deleteDatabase('ora_idb1');
console.log('資料庫已刪除');

預設情況IndexedDB沒有版本號 如下設定

if (db.version != "1.0"){
  openrequest = db.setVersion( "1.0");
  openrequest.onerror = function(e){
  alert("Something bad happened while trying to set version:" +
  e.target.errorCode);
};
 openrequest.onsuccess = function(e){
    alert("Database initialization complete. Database name: " + db.name +
    ", Version: " + db.version);
};
} else {
   alert("Database already initialized. Database name: " + db.name +
 " , Version: " + db.version);
 }

建立物件儲存空間

   openRequest.onupgradeneeded = function(e) {
   var thisDB = e.target.result;
    console.log("running onupgradeneeded");
     //利用contains方法檢視物件是否存在
    if(!thisDB.objectStoreNames.contains("people")) {
        var peopleOS = thisDB.createObjectStore("people",
        {keyPath: "email"}); //建立物件
 }

建立索引

    peopleOS.createIndex("gender", "gender", {unique:false});

建立事務

 //獲取事務
//預設為全部物件儲存,事務型別為read
var transaction = db.transaction(["people"],"readwrite");
 transaction.oncomplete = function(e){
    console.log('事務結束了');
}
transaction.onabort = function(e){
    console.log('事務被中止了');
}

add新增資料 put()方法也可

var person = {
    name:name,
    email:email,
    created:new Date().getTime()
}
//請求objectStore
var store = transaction.objectStore("people");  
//新增資料
var request = store.add(person);  

讀取資料

var request = store.get(person);  

更新資料

var request = store.put(person);  

刪除資料

var request = store.delete(key);

遊標檢索資料

獲取區間資料使用遊標,遊標通過物件空間的 openCursor 方法建立並開啟,openCursor 方法接收兩個引數,第一個是 IDBKeyRange 物件,該物件建立方法如下

// boundRange 表示主鍵值從1到10(包含1和10)的集合。
// 如果第三個引數為true,則表示不包含最小鍵值1,如果第四引數為true,則表示不包含最大鍵值10,默
   認都為false
var boundRange = IDBKeyRange.bound(1, 10, false, false);
 // onlyRange 表示由一個主鍵值的集合。only() 引數則為主鍵值,整數型別。
var onlyRange = IDBKeyRange.only(1);
// lowerRaneg 表示大於等於1的主鍵值的集合。
// 第二個引數可選,為true則表示不包含最小主鍵1,false則包含,預設為false
var lowerRange = IDBKeyRange.lowerBound(1, false);
// upperRange 表示小於等於10的主鍵值的集合。
// 第二個引數可選,為true則表示不包含最大主鍵10,false則包含,預設為false
var upperRange = IDBKeyRange.upperBound(10, false);  

openCursor 方法的第二個參數列示遊標的讀取方向

 next : 按主鍵值升序,主鍵值相等資料都被讀取
 nextunique : 按主鍵值升序,主鍵值相等讀取第一條資料
 prev : 按主鍵值降序,主鍵值相等資料都被讀取
 prevunique : 按主鍵值降序,主鍵值相等讀取第一條資料 

示例如下

var openrequest = indexedDB.open('ora_idb1', 2);
// ...
openrequest.onsuccess = function(e){
 db = e.target.result;
var tx = db.transaction('Users','readwrite');
var store = tx.objectStore('Users');
var range = IDBKeyRange.bound(1,10);
var req = store.openCursor(range, 'next');
req.onsuccess = function(){
    var cursor = this.result;
    if(cursor){
        console.log(cursor.value.userName);
        cursor.continue();
    }else{
        console.log('檢索結束');
    }
  }
}  

update() 方法更新該資料

cursor.updata({
userId : cursor.key,
userName : 'Hello',
age : 18
});

delete ()方法刪除該資料
continue() 方法讀取下一條資料
Promise風格的idb操作庫 github地址

相關文章