天天看點

html5的本地存儲,Html5本地存儲

使用場景,使用者狀态管理

1.存儲大小限制 僅4k左右,且每次請求都會發送回伺服器

2.單域名數量限制 50個左右

3.污染請求頭,浪費流量

二、localStorage 和 sessionStorage

用法

1.使用setItem方法設定存儲内容

2.使用getItem方法擷取存儲内容

3.使用removeItem方法删除存儲内容

4.使用clear方法清除所有内容

5.使用length屬性擷取存儲内容的個數

6.使用key方法擷取存儲字段

localStorage持久化,不會随着浏覽器的關閉而失效,存儲在硬碟中, 2.5MB 到 10MB 之間(各家浏覽器不同)。可以設定資料的存儲時間,過期資料清理,自行維護存儲空間。不提供搜尋功能,不能建立自定義的索引。

sessionStorage會随着網頁會話結束而失效,存儲在記憶體中。存儲流量不一,部分浏覽器不設限。

注意點

1.注意存儲容量超出配額 超出後會抛出異常

2.存儲類型的限制,僅能存儲字元串 隐式的類型轉換

3.sessionStorage失效機制

-重新整理頁面不會失效

-同一個域名下的不同标簽不共享

三、indexedDB資料庫

IndexedDB 就是浏覽器提供的本地資料庫,它可以被網頁腳本建立和操作。IndexedDB 允許儲存大量資料,提供查找接口,還能建立索引。這些都是 LocalStorage 所不具備的。就資料庫類型而言,IndexedDB 不屬于關系型資料庫(不支援 SQL 查詢語句),更接近 NoSQL 資料庫。

特點

(1)鍵值對儲存。 IndexedDB 内部采用對象倉庫(object store)存放資料。所有類型的資料都可以直接存入,包括 JavaScript 對象。對象倉庫中,資料以"鍵值對"的形式儲存,每一個資料記錄都有對應的主鍵,主鍵是獨一無二的,不能有重複,否則會抛出一個錯誤。

(2)異步。 IndexedDB 操作時不會鎖死浏覽器,使用者依然可以進行其他操作,這與 LocalStorage 形成對比,後者的操作是同步的。異步設計是為了防止大量資料的讀寫,拖慢網頁的表現。

(3)支援事務。 IndexedDB 支援事務(transaction),這意味着一系列操作步驟之中,隻要有一步失敗,整個事務就都取消,資料庫復原到事務發生之前的狀态,不存在隻改寫一部分資料的情況。

(4)同源限制。 IndexedDB 受到同源限制,每一個資料庫對應建立它的域名。網頁隻能通路自身域名下的資料庫,而不能通路跨域的資料庫。

(5)儲存空間大。 IndexedDB 的儲存空間比 LocalStorage 大得多,一般來說不少于 250MB,甚至沒有上限。

(6)支援二進制儲存。 IndexedDB 不僅可以儲存字元串,還可以儲存二進制資料(ArrayBuffer 對象和 Blob 對象)。

對象接口關系

html5的本地存儲,Html5本地存儲

關系圖.png

簡單事例

以資料庫dataObj為例,建立一個person倉庫,索引為name

1、打開或建立一個資料庫

// 相容性寫法

window.indexedDB =

window.indexedDB ||

window.mozIndexedDB ||

window.webkitIndexedDB ||

window.msIndexedDB;

window.IDBTransaction =

window.IDBTransaction ||

window.webkitIDBTransaction ||

window.msIDBTransaction;

window.IDBKeyRange =

window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;

// 相容性寫法

//打開或者建立資料庫,如果資料庫存在的時候就是打開,不存在的時候就是建立

//傳入資料庫的名稱和版本号,版本号為整數如果省略,打開已有資料庫時,預設為目前版本;建立資料庫時,預設為1

//這是一個異步操作,但是會立刻傳回一個 IDBOpenDBRequest 對象。

var request = window.indexedDB.open('dateObj', 1);

//删除資料庫,調用deleteDatabase()方法以後,目前資料庫的其他已經打開的連接配接都會接收到versionchange事件。

// window.indexedDB.deleteDatabase(databaseName);

// 建立資料庫與打開資料庫是同一個操作。如果指定的資料庫不存在,就會建立。

// 不同之處在于,後續的操作主要在upgradeneeded事件的監聽函數裡面完成,因為這時版本從無到有,是以會觸發這個事件。

var db;//資料庫IDBDatabase對象

request.onupgradeneeded = function (event) {

console.log('建立資料庫')

db = event.target.result;

var objectStore;

if (!db.objectStoreNames.contains('person')) { //檢查資料庫是否包含該對象倉庫

// 隻能在onupgradeneeded回調函數中建立存儲空間,而不能在資料庫打開後的success回調函數中建立。

// 删除倉庫對象(删除表格) db.deleteObjectStore(objectStoreName);

// db.close():關閉資料庫連接配接,實際會等所有事務完成後再關閉。

objectStore = db.createObjectStore('person', {

keyPath: 'id', //keyPath表示主鍵,(由于主鍵的值不能重複,是以上例存入之前,必須保證資料的email屬性值都是不一樣的),預設值為null

autoIncrement: true

//autoIncrement屬性表示,是否使用自動遞增的整數作為主鍵(第一個資料記錄為1,第二個資料記錄為2,以此類推),預設為false。

//一般來說,keyPath和autoIncrement屬性隻要使用一個就夠了,如果兩個同時使用,表示主鍵為遞增的整數,且對象不得缺少keyPath指定的屬性。

});

// IDBObject.createIndex()的三個參數分别為索引名稱、指定根據存儲資料的哪一個屬性來建構索引、配置對象(說明該屬性是否包含重複的值)。

//建立索引

objectStore.createIndex('name', 'name', {

unique: false//true的話表示不允許有重複的值

});

// 删除索引:objectStore.deleteIndex()

// 擷取所有索引對象:objectStore.index()

}

// 如果指定的版本号,大于資料庫的實際版本号,就會發生資料庫更新事件upgradeneeded

request.onupgradeneeded = function (event) {

db = event.target.result;

}

//失敗事件

request.onerror = function (event) {

console.log('資料庫打開報錯');

};

//成功事件

request.onsuccess = function (event) {

db = event.target.result;

//無論是建立還是打開資料庫,最後都會進入onsuccess

console.log('資料庫打開成功');

};

}

2、向person對象倉庫寫入資料記錄

function add(db, name) {

// 事務函數transaction的第一個參數為需要關聯的存儲空間,第二個可選參數為事務模式。

// readonly(隻讀)和readwrite(讀寫)。添加資料使用readwrite,讀取資料使用readonly。

// 第二個參數是可選的,省略時預設為readonly模式。

console.log('db', db.transaction(['person'], 'readwrite'))

var req = db.transaction(['person'], 'readwrite').objectStore('person').add({

name: name,

age: 29,

email: '[email protected]'

});

req.onsuccess = function (event) {

console.log('db', db)

console.log('資料寫入成功');

};

req.onerror = function (event) {

console.log('event', event)

console.log('資料寫入失敗');

}

}

3、在person對象倉庫讀取資料記錄

function read(db) {//讀取一條

var transaction = db.transaction(['person']);

var objectStore = transaction.objectStore('person');

var request = objectStore.get(1);//用主id去擷取到對應的值

request.onerror = function (event) {

console.log('事務失敗');

};

request.onsuccess = function (event) {

if (request.result) {

console.log('Name: ' + request.result.name);

console.log('Age: ' + request.result.age);

console.log('Email: ' + request.result.email);

} else {

console.log('未獲得資料記錄');

}

};

}

//使用索引擷取到具體的值

function readItem(db, name) {

var store = db.transaction(['person'], 'readonly')

.objectStore('person')

var index = store.index('name')

// var request=index.count(name)//符合索引的值的數量

// var request=index.get(name)//隻能擷取到第一個比對到的值

// var request=index.getAll(name)//擷取到所有比對到的值

// var request=index.getKey(name)//擷取到第一個比對到的值的主鍵的值

// var request=index.getAllKeys(name)//擷取到所有比對到的值的主鍵的值

var request = index.openCursor(name)

request.onsuccess = function (e) {

var result = e.target.result

console.log('result', result)

};

}

function readAll(db) {//讀取全部

var objectStore = db.transaction('person').objectStore('person');

// objectStore.openCursor()用于擷取一個指針對象。

// objectStore.openKeyCursor()用于擷取一個主鍵指針對象。

objectStore.openCursor().onsuccess = function (event) {

var cursor = event.target.result;

if (cursor) {

console.log('Id: ' + cursor.key);

console.log('Name: ' + cursor.value.name);

console.log('Age: ' + cursor.value.age);

console.log('Email: ' + cursor.value.email);

cursor.continue();

} else {

console.log('沒有更多資料了!');

}

};

}

4、在person對象倉庫更新資料記錄

function update(db) {

var request = db.transaction(['person'], 'readwrite')

.objectStore('person')

.put({

id: 1,

name: '李四',

age: 35,

email: '[email protected]'

});

request.onsuccess = function (event) {

console.log('資料更新成功');

};

request.onerror = function (event) {

console.log('資料更新失敗');

}

}

5、在person對象倉庫删除資料記錄

function remove(db) {

var request = db.transaction(['person'], 'readwrite')

.objectStore('person')

.delete(1);

request.onsuccess = function (event) {

console.log('資料删除成功');

};

}

四、參考文章