前言
後端經常使用數據庫作數據存儲,譬如MySql
、MongoDB
,緩存技術存儲數據,如Redis
、Memcached
;javascript
前端存儲數據目前經常使用的是Cookie
、Storage
、IndexedDB
html
Cookie
HTTP Cookie
(也叫Web Cookie
或瀏覽器Cookie
)是服務器發送到用戶瀏覽器並保存在本地的一小塊數據,它會在瀏覽器下次向同一服務器再發起請求時被攜帶併發送到服務器上。一般,它用於告知服務端兩個請求是否來自同一瀏覽器,如保持用戶的登陸狀態。Cookie
使基於無狀態的HTTP
協議記錄穩定的狀態信息成爲了可能。前端
分類
Cookie
老是保存在客戶端中(早期Java
中常常會將Cookie
與Session
做爲存儲技術進行比較,Session
是將數據保存在服務器端,大量的數據存儲會增長服務器的負擔),按在客戶端中的存儲位置,可分爲內存Cookie
和硬盤Cookie
。
內存Cookie
由瀏覽器維護,保存在內存中,瀏覽器關閉後就消失了,其存在時間是短暫的。硬盤Cookie
保存在硬盤裏,有一個過時時間,除非用戶手工清理或到了過時時間,硬盤Cookie
不會被刪除,其存在時間是長期的。因此,按存在時間,可分爲非持久Cookie
和持久Cookie
。java
建立Cookie
Set-Cookie
響應頭部和Cookie
請求頭部節
服務器使用Set-Cookie
響應頭部向用戶代理(通常是瀏覽器)發送Cookie
信息。一個簡單的Cookie
可能像這樣:Set-Cookie: <cookie名>=<cookie值>
web
服務器經過該頭部告知客戶端保存Cookie
信息數據庫
瀏覽器環境下獲取非HttpOnly
標記的 cookie
後端
var cookies = document.cookie;複製代碼複製代碼
Cookie的缺點
Cookie
會被附加在每一個HTTP
請求中,因此無形中增長了流量。因爲在HTTP
請求中的Cookie
是明文傳遞的,因此安全性成問題,除非用HTTPS
。api
Cookie
的大小限制在4KB
左右,對於複雜的存儲需求來講是不夠用的。瀏覽器
Cookie的簡單封裝
設置Cookie
時通常會將路徑和過時時間一併設置,注意過時時間須要轉換成GMT
或者UTC
緩存
代碼
(function IIFE(root){
function getCookie(cname, defaultValue){
var value = new RegExp('(^|;| )'+cname+'=([^;]*?)(;|$)', 'g').exec(document.cookie);
console.log('value:', value);
if(!value) return defaultValue;
return value[2];
}
function setCookie(cname, cvalue, day, path){
day = day || 1;
path = path || '/';
var date = new Date();
date.setTime(date.getTime() + day * 24 * 60 * 60 * 1000);
document.cookie = cname+'='+cvalue+'; expires=' + date.toGMTString() + '; path='+path+'; ';
}
function deleteCookie(cname){
setCookie(cname, null, -1);
}
root.Util = {
getCookie: getCookie,
setCookie: setCookie,
deleteCookie: deleteCookie,
}
})(window);複製代碼複製代碼
測試結果
Storage
做爲 Web Storage API
的接口,Storage
提供了訪問特定域名下的會話存儲(session storage
)或本地存儲(local storage
)的功能,例如,能夠添加、修改或刪除存儲的數據項。
若是你想要操做一個域名的會話存儲(session storage
),能夠使用 window.sessionStorage
若是想要操做一個域名的本地存儲(local storage
),能夠使用 window.localStorage
。
sessionStorage
和localStorage
的用法是同樣的,區別在於sessionStorage
會在會話關閉也就是瀏覽器關閉時失效,而localStorage
是將數據存儲在本地,不受關閉瀏覽器影響,除非手動清除數據
相關的api你們能夠參考
developer.mozilla.org/zh-CN/docs/…
代碼
(function IIFE(){
if(!window.localStorage){
alert('your browser is not support localStorage!');
return;
}
function getStorage(sname, defaultValue){
//result = window.localStorage.sname
//result = window.localStorage[sname]
var result = window.localStorage.getItem(sname);
return result || defaultValue;
}
function setStorage(sname, svalue){
window.localStorage.setItem(sname, svalue);
}
function removeItem(sname){
window.localStorage.removeItem(sname);
}
function getKey(keyIndex){
return window.localStorage.key(keyIndex);
}
function getAllKeys(){
var arr = [];
for(var i=0;i<window.localStorage.length;i++){
arr.push(window.localStorage.key(i));
}
return arr;
}
function clearStorage(){
window.localStorage.clear();
}
function onStorageChange(event){
console.log(event)
}
window.addEventListener('storage', onStorageChange);
window.Util = {
getStorage: getStorage,
setStorage: setStorage,
removeItem: removeItem,
getKey: getKey,
getAllKeys: getAllKeys,
clearStorage: clearStorage,
}
})();複製代碼複製代碼
測試結果
IndexedDB
隨着瀏覽器的功能不斷加強,愈來愈多的網站開始考慮,將大量數據儲存在客戶端,這樣能夠減小從服務器獲取數據,直接從本地獲取數據。
現有的瀏覽器數據儲存方案,都不適合儲存大量數據:Cookie
的大小不超過 4KB
,且每次請求都會發送回服務器;LocalStorage
在 2.5MB
到 10MB
之間(各家瀏覽器不一樣),並且不提供搜索功能,不能創建自定義的索引。因此,須要一種新的解決方案,這就是 IndexedDB
誕生的背景。
通俗地說,IndexedDB
就是瀏覽器提供的本地數據庫,它能夠被網頁腳本建立和操做。IndexedDB
容許儲存大量數據,提供查找接口,還能創建索引。這些都是 LocalStorage
所不具有的。就數據庫類型而言,IndexedDB
不屬於關係型數據庫(不支持 SQL
查詢語句),更接近 NoSQL
數據庫。
IndexedDB
相關API
可參考
代碼
(function IIFE(){
if(!window.indexedDB){
alert('your browser is not support indexedDB!');
return;
}
var request = window.indexedDB.open('person', 1);
var db;
request.onerror = function (event) {
console.log('數據庫打開報錯');
};
request.onsuccess = function (event) {
db = request.result;
console.log('數據庫打開成功');
};
request.onupgradeneeded = function(event) {
console.log('onupgradeneeded...');
db = event.target.result;
var objectStore = db.createObjectStore('person', { keyPath: 'id' });
objectStore.createIndex('name', 'name', { unique: false });
objectStore.createIndex('email', 'email', { unique: true });
}
function add(obj) {
var request = db.transaction(['person'], 'readwrite')
.objectStore('person')
.add(obj)
//.add({ id: 1, name: 'ccy', age: 18, email: 'test@example.com' });
request.onsuccess = <span class="hljs-keyword">function</span> (event) {
console.log(<span class="hljs-string">'數據寫入成功'</span>);
};
request.onerror = <span class="hljs-keyword">function</span> (event) {
console.log(<span class="hljs-string">'數據寫入失敗'</span>);
}
}
<span class="hljs-keyword">function</span> <span class="hljs-built_in">read</span>(index) {
var transaction = db.transaction([<span class="hljs-string">'person'</span>]);
var objectStore = transaction.objectStore(<span class="hljs-string">'person'</span>);
var request = objectStore.get(index);
request.onerror = <span class="hljs-keyword">function</span>(event) {
console.log(<span class="hljs-string">'事務失敗'</span>);
};
request.onsuccess = <span class="hljs-keyword">function</span>(event) {
<span class="hljs-keyword">if</span> (request.result) {
console.log(<span class="hljs-string">'Name: '</span> + request.result.name);
console.log(<span class="hljs-string">'Age: '</span> + request.result.age);
console.log(<span class="hljs-string">'Email: '</span> + request.result.email);
} <span class="hljs-keyword">else</span> {
console.log(<span class="hljs-string">'未得到數據記錄'</span>);
}
};
}
<span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">readAll</span></span>() {
var objectStore = db.transaction(<span class="hljs-string">'person'</span>).objectStore(<span class="hljs-string">'person'</span>);
objectStore.openCursor().onsuccess = <span class="hljs-keyword">function</span> (event) {
var cursor = event.target.result;
<span class="hljs-keyword">if</span> (cursor) {
console.log(<span class="hljs-string">'Id: '</span> + cursor.key);
console.log(<span class="hljs-string">'Name: '</span> + cursor.value.name);
console.log(<span class="hljs-string">'Age: '</span> + cursor.value.age);
console.log(<span class="hljs-string">'Email: '</span> + cursor.value.email);
cursor.continue();
} <span class="hljs-keyword">else</span> {
console.log(<span class="hljs-string">'沒有更多數據了!'</span>);
}
};
}
<span class="hljs-keyword">function</span> update(obj) {
var request = db.transaction([<span class="hljs-string">'person'</span>], <span class="hljs-string">'readwrite'</span>)
.objectStore(<span class="hljs-string">'person'</span>)
.put(obj)
//.put({ id: 1, name: <span class="hljs-string">'李四'</span>, age: 35, email: <span class="hljs-string">'lisi@example.com'</span> });
request.onsuccess = <span class="hljs-keyword">function</span> (event) {
console.log(<span class="hljs-string">'數據更新成功'</span>);
};
request.onerror = <span class="hljs-keyword">function</span> (event) {
console.log(<span class="hljs-string">'數據更新失敗'</span>);
}
}
<span class="hljs-keyword">function</span> remove(index) {
var request = db.transaction([<span class="hljs-string">'person'</span>], <span class="hljs-string">'readwrite'</span>)
.objectStore(<span class="hljs-string">'person'</span>)
.delete(index);
request.onsuccess = <span class="hljs-keyword">function</span> (event) {
console.log(<span class="hljs-string">'數據刪除成功'</span>);
};
}
window.util = {
add: add,
<span class="hljs-built_in">read</span>: <span class="hljs-built_in">read</span>,
<span class="hljs-built_in">read</span>All: <span class="hljs-built_in">read</span>All,
update: update,
remove: remove,
}
複製代碼
複製代碼request.onsuccess = <span class="hljs-keyword">function</span> (event) {
console.log(<span class="hljs-string">'數據寫入成功'</span>);
};
request.onerror = <span class="hljs-keyword">function</span> (event) {
console.log(<span class="hljs-string">'數據寫入失敗'</span>);
}
}
<span class="hljs-keyword">function</span> <span class="hljs-built_in">read</span>(index) {
var transaction = db.transaction([<span class="hljs-string">'person'</span>]);
var objectStore = transaction.objectStore(<span class="hljs-string">'person'</span>);
var request = objectStore.get(index);
request.onerror = <span class="hljs-keyword">function</span>(event) {
console.log(<span class="hljs-string">'事務失敗'</span>);
};
request.onsuccess = <span class="hljs-keyword">function</span>(event) {
<span class="hljs-keyword">if</span> (request.result) {
console.log(<span class="hljs-string">'Name: '</span> + request.result.name);
console.log(<span class="hljs-string">'Age: '</span> + request.result.age);
console.log(<span class="hljs-string">'Email: '</span> + request.result.email);
} <span class="hljs-keyword">else</span> {
console.log(<span class="hljs-string">'未得到數據記錄'</span>);
}
};
}
<span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">readAll</span></span>() {
var objectStore = db.transaction(<span class="hljs-string">'person'</span>).objectStore(<span class="hljs-string">'person'</span>);
objectStore.openCursor().onsuccess = <span class="hljs-keyword">function</span> (event) {
var cursor = event.target.result;
<span class="hljs-keyword">if</span> (cursor) {
console.log(<span class="hljs-string">'Id: '</span> + cursor.key);
console.log(<span class="hljs-string">'Name: '</span> + cursor.value.name);
console.log(<span class="hljs-string">'Age: '</span> + cursor.value.age);
console.log(<span class="hljs-string">'Email: '</span> + cursor.value.email);
cursor.continue();
} <span class="hljs-keyword">else</span> {
console.log(<span class="hljs-string">'沒有更多數據了!'</span>);
}
};
}
<span class="hljs-keyword">function</span> update(obj) {
var request = db.transaction([<span class="hljs-string">'person'</span>], <span class="hljs-string">'readwrite'</span>)
.objectStore(<span class="hljs-string">'person'</span>)
.put(obj)
//.put({ id: 1, name: <span class="hljs-string">'李四'</span>, age: 35, email: <span class="hljs-string">'lisi@example.com'</span> });
request.onsuccess = <span class="hljs-keyword">function</span> (event) {
console.log(<span class="hljs-string">'數據更新成功'</span>);
};
request.onerror = <span class="hljs-keyword">function</span> (event) {
console.log(<span class="hljs-string">'數據更新失敗'</span>);
}
}
<span class="hljs-keyword">function</span> remove(index) {
var request = db.transaction([<span class="hljs-string">'person'</span>], <span class="hljs-string">'readwrite'</span>)
.objectStore(<span class="hljs-string">'person'</span>)
.delete(index);
request.onsuccess = <span class="hljs-keyword">function</span> (event) {
console.log(<span class="hljs-string">'數據刪除成功'</span>);
};
}
window.util = {
add: add,
<span class="hljs-built_in">read</span>: <span class="hljs-built_in">read</span>,
<span class="hljs-built_in">read</span>All: <span class="hljs-built_in">read</span>All,
update: update,
remove: remove,
}
複製代碼})();複製代碼複製代碼
測試結果
後記
瀏覽器存儲技術目前流行的基本就上面介紹的三種,以前出現的webSql
因爲用方言SQLlite
致使沒法統一,也就是說這是一個廢棄的標準。
localStorage
、indexedDB
這裏沒有作詳細的介紹,只是簡單的給出示例代碼作作演示,不熟悉的能夠查閱相關API
。
參考資料
developer.mozilla.org/zh-CN/docs/…
developer.mozilla.org/zh-CN/docs/…
zh.wikipedia.org/wiki/Cookie
www.ruanyifeng.com/blog/2018/0…
wangdoc.com/javascript/…