1、前言web
這章很是重要,因爲以後須要負責平臺手機APP的往後維護,如何讓用戶在離線狀態下正常使用,以及聯網後的數據合併變得很是重要。面試
2、內容數據庫
離線檢測windows
navigator.online —— 屬性爲true時表示設備能上網
online() —— 當網絡從離線轉在線觸發
offline() —— 當網絡從在線轉離線觸發
navigator.online取得初始狀態,而後經過上述兩個事件肯定網絡鏈接狀態是否變化
數據存儲跨域
//Cookie
數量:每一個域的cookie總數是有限的,通常每一個域最多30~50個cookie
長度:整個cookie的長度限制在4095B之內
構成:
1.名稱 URL編碼
2.值 URL編碼
3.域
4.路徑 —— 指定域下的某個路徑才能訪問
5.失效時間
6.安全標誌 —— 指定後cookie只有在使用SSL鏈接的時候才發送服務器
代碼:
var CookieUtil = {
// 獲取Cookie
get:function(name){
var cookieName = encodeURIComponent(name)+"=",
cookieStart = document.cookie.indexOf(cookieName),
cookieValue = null;
if(cookieStart > -1){
var cookieEnd = document.cookie.indexOf(";",cookieStart);
if(cookieEnd == -1){
cookieEnd = document.cookie.length;
}
cookieValue = decodeURIComponent(document.cookie.substring(
cookieStart + cookieName.length, cookieEnd));
}
return cookieValue;
},
//設置Cookie
set:function(name, value, expires, path, domain, secure){
var cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value);
if(expires instanceof Date){
cookieText += "; expires=" + expores.toGMTString();
}
if(path){
cookieText += "; path=" + path;
}
if(domain){
cookieText += "; domain=" + domain;
}
if(secure){
cookieText += "; secure";
}
document.cookie = cookieText;
},
//刪除Cookie
unset:function(name,path,domain,secure){
this.set{name, "", new Date(0), path, domain, secure};
}
}
//子Cookie
使用cookie值來存儲多個名稱值對
name=name1=value1&name2=value2&name3=value3
總結:
1.cookie太大容易影響性能
2.不能在cookie中存儲重要和敏感的數據
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Web存儲機制 —— Web Storage
1.提供一種在cookie以外存儲會話數據的途徑
2.提供一種存儲大量能夠跨會話存在的數據的機制
Storage類型,有如下方法:
clear() —— 刪除全部值
getItem(name) —— 根據名稱得到值
key(index) —— 得到index處的值的名字
removeItem(name) —— 刪除由name指定的名值對
setItem(name,valie) —— 爲指定的name設置一個對應值
sessionStorage對象
該對象存儲特定與某個會話的數據,該數據只保存到瀏覽器關閉,它是Storage的一個實例
//使用方法存儲數據
sessionStorage.setItem("name", "Nicholas");
//使用屬性存儲數據
sessionStorage.book = "Nicholas";
//遍歷
for(var key in sessionStorage){
var value = sessionStorage.getItem(key);
}
用途:sessionStorage對象主要用於僅針對會話的小段數據的存儲
globalStorage對象
用途:globalStorage對象主要用於跨越會話存儲數據,但有特定的訪問限制,須要指定域
globalStorage["wrox.com"]對象是Storage的一個實例
使用時必定要指定一個域名!!!
//保存數據
globalStorage["wrox.com"].name = "Nicholas";
//獲取數據
var name = globalStorage["wrox.com"].name;
localStorage對象
它是Storage的一個實例不能給localStorage指定任何訪問規則;規則事先就設定好了
要訪問一個localStorage對象,頁面必須來自同一域名(子域名無效),使用同一種協議,在同一端口上
至關於globalStorage[location.host]
storage事件
在Storage對象進行任何修改,都會在文檔上觸發storage事件,有如下屬性:
domain:發送變化的存儲空間的域名
key:設置或刪除的鍵名
newValue:若是是設置值,則是新值;若是是刪除鍵,則是null
oldValue:鍵被更改以前的值
總結:
1.因瀏覽器不一樣而對存儲空間大小有限制
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//IndexedDB —— 在瀏覽器保存結構化數據的一種數據庫
IndexedDB設計的操做徹底是異步進行的
差很少每一次IndexedDB操做,都須要註冊onerror或onsuccess事件
var indexedDB = window.indexedDB || windows.msIndexedDB || window.mozIndexedDB || window.webkitIndexedDB;
1.數據庫
var request, database;
request = indexedDB.open("admin"); //傳入數據庫名稱
request.onerror = function(event){
alert("open fail" + event.target.errorCode); //出現錯誤
};
request.onsucess = function(event){
database = event.target.result; //獲得數據庫實例
};
默認狀況下,IndexedDB數據庫是沒有版本號的,最好一開始就指定
if(database.version != "1.0"){
request = database.setVersion("1.0");
request.onerror = function(event){};
request.onsuccess = function(event){};
}else{}
2.對象存儲空間
數據庫創建鏈接後,下一步是使用對象存儲空間。
若是數據庫的版本與傳入的版本不匹配,那麼可能須要建立一個新的對象存儲對象。
假設一條記錄的對象以下所示:
var user = {
username:"007",
firstName:"James",
lastName:"Bond",
password:"foo"
};
var store = db.createObjectStore("users",{keyPath:"username"}); //指定空間名稱及keyPath做爲鍵
//使用add()或put()添加數據 —— store.add() / store.put()
//其中add()方法重寫會返回錯誤,put()重寫原有對象沒問題
3.事務
建立完對象存儲空間以後,接下來全部操做都是經過事務來完成的
調用transaction()建立事務
var transaction = db.transaction();
//或
var transaction = db.transaction("users"); //訪問一個對象
//或
var transaction = db.transaction("users","anotherStore"); //訪問多個對象
上述方法都是以只讀方式訪問數據,若是修改訪問方式:
var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction;
var transaction = db.transaction("users",IDBTransaction.READ_WRITE);
其中:
IDBTransaction.READ_ONLY —— 只讀
IDBTransaction.READ_WRITE —— 讀寫
IDBTransaction.VERSION_CHANGE —— 改變
使用objectStore()並傳入存儲空間的名稱就能夠訪問特定的存儲空間:
var request = db.transaction("users").objectStore("users").get("007");
request.onerror = function(event){
//do something
}
request.onsuccess = function(event){
var result = event.target.result;
alert(result.firstName);
}
事件自己也有事件處理程序:
transaction.onerror = function(event){//整個事務都被取消};
transaction.oncomplete = function(event){
//整個事務都成功完成,但訪問不到event中的任何數據,
//必須在相應請求的onsuccess事件中才能訪問
};
4.使用遊標查詢
檢索多個對象時,須要在事務內建立遊標 openCursor()
var store = db.transaction("users").objectStore("users"),
request = store.openCursor();
request.onerror = function(event){};
request.onsuccess = function(event){
var cursor = event.target.result; //返回一個IDBCursor實例
if(cursor){ //必需要檢查
//do something
}
};
IDBCursor屬性包含:
direction —— 遊標移動方向
IDBCursor.NEXT(0) 下一項
IDBCursor.NEXT_NO_DUPLICATE(1) 下一個不重複項
IDBCursor.PREV(2) 前一項
IDBCursor.PREV_NO_DUPLICATE 前一個不重複項
key —— 對象的鍵
value —— 實際的對象,顯示前須要使用JSON.stringify(value)來轉成Json對象
primaryKey —— 遊標使用的鍵
遊標能夠更新個別的記錄 —— cursor.update()
request.onsuccess = function(event){
var cursor = event.target.result,
value,
updateRequest;
if(cursor){
if(cursor.key == "foo"){
value = cursor.value;
value.password = "magic!";
updateRequest = cursor.update(value); //請求保存更新
udpateRequest.onsuccess = function(){//處理成功};
udpateRequest.onerror = function(){//處理成功};
}
}
}
遊標也能夠調用cursor.delete()刪除相應記錄,
若是當前事務沒有修改對象存儲空間的權限,update()與delete()會拋出錯誤
默認狀況下,每一個遊標只發起一次請求,要想發起另外一次請求,能夠調用:
continue(key) —— 移動到結果集中的下一項
advance(count) —— 向前移動count指定的項數
5.鍵範圍
單純經過遊標查詢數據的方式太有限,鍵範圍增長了靈活性
var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;
only():
var onlyRange = IDBKeyRange.only("007");
lowerBound():
var lowerRange = IDBKeyRange.lowerBound("007"); //從007開始到最後,包含007
var lowerRange = IDBKeyRange.lowerBound("007",true); //從007開始到最後,不包含007
upperBound():
var upperRange = IDBKeyRange.upperBound("007"); //從007開始往上,包含007
var upperRange = IDBKeyRange.upperBound("007",true); //從007開始往上,不包含007
Bound():
var boundRange = IDBKeyRange.bound("下界鍵","上界鍵",是否跳過下界,是否跳過上界);
例:
var store = db.transaction("users").objectStore("users");
range = IDBKeyRange.bound("007","ace");
request = store.openCursor(range);
request.onsuccess = function(event){
var cursor = event.target.result;
if(cursor){};
}
6.設定遊標方向
var IDBCursor= window.IDBCursor || window.webkitIDBCursor;
var store = db.transaction("users").objectStore("users"),
request = store.openCursor(null, IDBCursor.NEXT_NO_DUPLICATE);//null爲默認全範圍
7.索引
對於某些數據,可能要爲一個對象存儲空間指定多個鍵,即主鍵與索引鍵
首先引用對象存儲空間,而後調用createIndex()
var store = db.transaction("users").objectStore("users"),
index = store.createIndex("username","username",{unique:false}); //其它空間也有可能含username
第一個參數:索引的名稱
第二個參數:索引的屬性的名字
第三個參數:是否在全部記錄中惟一
使用一個已經存在的名爲"username"的索引:
var store = db.transaction("users").objectStore("users");
index = store.index("username");
request = index.openCursor();
//若是隻返回每條記錄主鍵的遊標:
request = index.openKeyCursor();
request.onsuccess = function(event){
//event.result.key中保存索引鍵
//event.result.value保存主鍵
};
//get()方法可以從索引中取得一個對象
request = index.get("007");
//要根據給定的索引鍵取得主鍵,使用getKey()
request = index.getKey("007");
IDBIndex對象含如下屬性:
name —— 索引的名稱
keyPath —— 傳入createIndex()中的屬性路徑
objectStore —— 索引的對象存儲空間
unique —— 標識索引鍵是否惟一
store.indexNames能訪問到爲該空間創建的全部索引
store.deleteIndex("name")則能夠根據索引的名稱刪除索引
8.併發問題
若是瀏覽器的兩個不一樣的標籤頁打開了同一頁面,那麼一個頁面試圖更新另外一個頁面還沒有
準備就緒的數據庫問題就有可能發生。所以,只有當瀏覽器中僅有一個標籤頁使用數據庫狀況下,調用setVersion()才能完成操做
正確的方式:
剛打開數據庫時,要記着指定onversionchange事件處理程序。當同一個來源的另外一個標籤頁調用setVersion()時,就會執行這個回調:
var request, database;
request = indexedDB.open("admin");
request.onsuccess = function(event){
database = event.target.result;
database.onversionchange = function(){
database.close()
};
}
在你想要更新數據庫的版本但另外一個標籤頁已經打開數據庫的狀況下,要觸發onblocked事件:
var request= database.setVersion("2.0");
request.onblocked = function(){
alert("Please close all other tabs");
};
request.onsuccess = function(){
//do something
};
總結:
1.不能跨域共享信息2.大約5MB或50MB的空間限制