四種有能力取代Cookies的客戶端Web儲存方案
目前在使用者的網路瀏覽器中儲存大量資料需要遵循幾大現有標準,每一種標準都擁有自己的優勢、短板、獨特的W3C標準化狀態以及瀏覽器支援級別。但無論如何,這些標準的實際表現都優於廣泛存在的cookies機制。
今天的Web應用程式開始在客戶端中執行大量資料處理工作,甚至可能需要以離線方式完成任務。可以說,客戶端資料儲存對於下一代Web應用程式的發展起到了至關重要的作用。
然而直到現在,cookies仍然是使用者瀏覽器中最常見的資料儲存機制。如果一款Web應用需要重複訪問某些資料,則只有兩種方式可供選擇:要麼再次向伺服器傳送請求以獲取資料,要麼讀取儲存在cookies中的內容。
cookies機制只能提供有限的儲存空間——最多4K或者4096位元組——因此總量較大的資料會被拆分成4K大小的塊從而加以明確而直接地管理。
但這種方式對於儲存的協作及管理而言顯然並不可行,因此我們需要拿出一套新的替代性方案。
cookies的承受能力太過孱弱
網路瀏覽器最初只是通過HTTP並解析HTML實現應用程式對文件內容的載入。但在此後不久,第一款網景瀏覽器出現了,它滿足了使用者的一系列實際需求,但卻需要利用本質上無狀態的HTTP協議來通過某些機制實現狀態追蹤。面對這一問題,Lou Montulli於1994年創造了瀏覽器cookie(當初被稱為‘magic cookie’),並首次亮相於Mosiac網景瀏覽器0.9b版本之上。
在通用閘道器介面(簡稱CGI)提供的伺服器端指令碼訪問功能與cookies的共同輔助下,最早的Web應用程式終於變成現實。最終,我們開始沿著這條小路將瀏覽器轉化成為一種通用的應用程式平臺。
然而cookies機制存在著嚴重缺陷。正如前面所提到,它只能儲存極少量資料,而且很容易受到各類攻擊活動的影響,這樣的狀況讓我們很難利用其儲存個人資訊及敏感資料、從而極大限制了它的使用範圍。
cookies會介入到從瀏覽器發向伺服器端的每一條HTTP請求當中。假設一個網頁中包含的四張圖片、一個外部CSS文件外加JavaScript文件。系統會為該域設定一個4K的cookie,瀏覽器則分四次將該cookie轉發至伺服器端——一次針對HTML頁面、一次針對每張圖片、一次針對CSS文件再加上一次針對JavaScript文件。
令問題進一步複雜化的原因在於,這個理論上為4K大小的cookie需要從瀏覽器端傳輸至伺服器端;由於大部分使用者使用的是非同步網際網路連線,即上傳速度低於下載速度,因此在HTTP響應頭中傳輸cookie資料一定會造成不必要的頻寬佔用。
由於上述限制因素的存在,大部分cookies的體積都要遠小於4K。谷歌建議每個cookie的實際大小不要超過400位元組(或者200個字元),從而實現最佳效能表現。他們還建議稱,在圖片、CSS以及JavaScript等來自獨特域的靜態檔案應該禁用cookies機制。
由於cookies機制在本地儲存領域存在諸多問題,目前已經出現一系列新興方案,旨在撥亂反正、保質保量完成任務。近幾個月以來,已經有兩款方案走上正軌、得到W3C的強烈推薦——它們能夠很好、甚至比我們預想中更好地幫助瀏覽器支援本地儲存功能。
目前我們可以從四種主流客戶端資料儲存機制中做出選擇,它們分別是:Web SQL、IndexedDB、Web Storage以及Application Cache。下面我們就逐一對每套方案加以評述,並探討它們在運作及效果方面的各自特性。
Web SQL: 擅長(但是否有些過時?)資料庫建立與執行
Web SQL是一種利用資料庫進行資料儲存並利用SQL處理檢索任務的API。最近,Safari、Chrome以及Opera等知名瀏覽器紛紛在Web SQL與IndexedDB的競爭之中選擇了前者。不過2010年時,SQLite還是惟一一款能夠與Web SQL協作的資料庫,而W3C出於安裝基礎較小的理由而停止對這套方案進行支援。
Web SQL的工作機制相當新奇,下面我們就一起來看示例程式碼。
Web SQL資料庫的使用感受與關係類資料庫及SQL非常相似。使用這款資料庫的第一步在於建立並開啟。如果大家不希望額外建立一套資料庫,那麼完全可以直接開始使用,API本身會自動完成建立工作。
下面我們來看一部分用於資料庫建立的程式碼:
var db = openDatabase('cats', '1.0', 'a catalog of my cats', 2 *1024 * 1024);
按照從左到右的順序,openDatabase後面的引數依次代表著資料庫名稱、版本號、文字說明以及預計資料庫大小。
資料庫建立完成之後,大家就可以著手使用了。在WebSQL資料庫上執行SQL與建立事務物件並加以執行一樣簡單:
db.transaction(function (tx) { tx.executeSql('CREATE TABLE cats (id unique, name)'); tx.executeSql('INSERT INTO cats (id,name) VALUES (1,"Mr. Jones")'); });
儘管Safari、Chrome、Opera以及Mobile Safari都支援這款API,但自2010年以來Web SQL就沒有發生過任何變化,因此它不太可能成為本地儲存的新型標準。
Web Storage: 取cookies所長、去cookies所短
Web Storage利用一種簡單的方法在使用者的瀏覽器中儲存鍵/值對。但它與cookies之間的相似之處也就僅此而已了。
•Web Storage是一套永續性方案。一旦某個值被儲存之後就不會再消失或者終止,除非被應用程式或使用者明確刪除。
•Web Storage能夠處理大量資料。目前瀏覽器的總體儲存區域大小最高為5MB。
•Web Storage無需依賴於伺服器,而且不必向伺服器端傳送資料。當然,大家可以隨意實現本地化資料儲存並將其與伺服器進行非同步式同步,但Web Storage的表現始終出色而且在離線與線上狀況下都能正常生效。
•Web Storage提供四種主要方法——getItem(鍵);setItem(鍵、值);removeItem(鍵)以及clear()。
最後,Web Storage包含兩種完全不同的儲存型別:SessionStorage以及LocalStorage。
SessionStorage的作用在於保證被儲存在當前瀏覽器視窗當中的資料僅作用於該視窗。舉例來說,當大家使用電子商務類應用程式時,利用SessionStorage來記錄使用者的購物車資訊能夠避免誤操作所帶來的二次購買狀況。
下面再來看LocalStorage,它專門負責儲存可同時作用於同一瀏覽器之下各視窗及標籤之間的資料。因此,如果大家在Chrome當中開啟了三個關於同一網站的視窗,那麼三者能夠共同使用同一套LocalStorage容器。相比之下,如果我們開啟三個內容彼此獨立的網站視窗,那麼每一個都將使用彼此獨立的容器。同樣,如果大家在不同的瀏覽器當中開啟同一個網站,那麼每種瀏覽器都需要使用屬於自己的容器,因此無法共享同一套通用的執行環境。
要設定一套新的鍵-值對並進行檢索,大家可以使用下列JavaScript命令:
//first set firstname equal to Sparky. localStorage.setItem( "firstname", "Sparky" ); //next, get the value of firstname (hint, it will be Sparky). localStorage.getItem( "firstname" );
今年夏天,Web Storage API正式獲得W3C推薦標準這一殊榮。展望未來,Web Storage完全有可能在一切原本cookies發揮作用的舞臺上成為新的處理方案。
但Web Storage能做的還很多。如果大家的資料集並不太大,Web Storage還提供另一種可能是最為簡便的處理辦法——甚至比cookies更簡便——從而順利搞定瀏覽器中鍵-值對的設定與檢索工作。
IndexedDB:可搜尋且不存在檔案大小限制
Indexed Database是一款利用索引化事務性資料庫對使用者計算機上的資料進行儲存與索引的API。IndexedDB帶來更快速、更精妙的資料儲存與檢索效果,在這方面採用簡單鍵-值對儲存機制的cookies以及Web Storage都只能甘拜下風。
與Web Storage一樣,IndexedDB API在今年夏天(也就是2013年7月)向Web標準邁進了一大步,成為W3C候選推薦名單中的一員。
與Web Storage相比,IndexedDB帶來四項具體提升:
- 能夠對索引資料進行高效搜尋。
- 資料庫能夠將多個值儲存為一個鍵,而鍵-值機制則要求每個鍵都必須惟一。
- 事務型資料庫提供多項針對系統及應用程式故障的保護措施。如果事務流程未能正常完成,則將通過回滾方式進行恢復。
- IndexedDB資料庫對資料內容的大小不加限制。在火狐當中,瀏覽器會要求利用許可權將資料庫的容量提升到超過50MB,而IndexedDB的實際資料儲存量限制直接取決於分卷或者磁碟驅動器本身的容量極限。
除了Safari之外的所有主流瀏覽器都已經支援IndexedDB。不過由於Safari支援Web SQL,因此我們完全可以利用IndexedDB夾層(或者被稱為shim)通過Web SQL實現IndexedDB的功能與語法。
要使用IndexedDB,第一步需要開啟一套資料庫。
var request = indexedDB.open("myDatabase");
在資料庫建立完成之後,大家可以建立一個儲存物件(與表格非常類似)並向其中新增資料。假設我們需要向其中新增如下資料:
const petData = [ { id: "00-01", firstname: "Butters", age: 2, type: "dog" }, { id: "00-02", firstname: "Sammy", age: 2, type: "dog" } ];
接下來,我們可以建立資料儲存機制並通過下列程式碼加以使用。請注意onupgradeneeded的處理方式:我們在改變資料庫結構時需要用到這一方法。
request.onupgradeneeded = function(event) { var db = event.target.result; var objectStore = db.createObjectStore("customers", {keyPath: "id"}); for (var i in customerData) { objectStore.add(customerData[i]); } }
IndexedDB擅長於搜尋大型資料庫集,並能夠通過將結構化資料移動至客戶端來提高Web應用程式的效能表現。目前它已經非常接近W3C的推薦級別,而且能夠被用於全部瀏覽器平臺——儘管具體實施方式有所區別,如前文所述,在Safari中需要借用夾層機制。
Application Cache: 讓離線客戶端儲存成為現實
Application Cache與前面提到的其它客戶端資料儲存APi都不一樣,但它同樣值得關注,因為它已經成為離線客戶端Web應用程式的重要組成部分。
Application Cache使用的是一套快取列表。所謂列表,只是一個非常簡單的文字文件,其中列舉了所有應該或不應該通過快取機制處理的資源條目,從而指導瀏覽器下載特定檔案、加以儲存並在必要時予以使用——而不必再向伺服器發出重複請求。目前所有主流網路瀏覽器都支援Application Cache機制。
要使用Application Cache,我們需要首先在包含有快取物件檔案的網站中儲存一個副檔名為為.appcache的文字檔案。根據所使用Web伺服器的具體型別,我們可能需要為.appcache檔案建立一個自定義MIME型別以確保它們能夠正確作用於瀏覽器並可被作為應用程式快取檔案讀取。
下面我們列舉一個快取列表檔案作為範例:
CACHE MANIFEST CACHE: /css/styles.css /js/javascript.css /img/logo.gif FALLBACK: /img/weathertoday.png /img/weathernotavailable.png NETWORK:
現在我們來詳細解讀其中的內容:
- CACHE部分用於告知瀏覽器哪些資源需要進入快取以實現離線檢視。這些檔案會一直保留於快取當中中,直到快取列表發生變化。請記住這項要求,非常重要。
- FALLBACK部分則用於告知瀏覽器哪些要顯示的檔案會取代非快取資源。舉例來說,在上面的FALLBACK部分中,我們可以推測如果latestweather.png圖片無法被正確下載,那麼當前天氣狀況無法在離線狀態下實現圖片顯示。
- NETWORK部分用於告知瀏覽器哪些資源只能通過線上模式進行獲取。結尾部分的星號表示目前快取中不存在任何一種網路資源。
Application Cache是一款出色的工具,只要使用得當、它幾乎沒有什麼缺點。其實正確使用是一門學問:如果大家單純把網站上的所有內容都新增到快取當中,那麼訪問者們會很快發現網站內容永遠不會發生變化。如果大家只把變化頻率不高的內容儲存在快取當中,或者努力保證快取列表始終處於最新並在上傳檔案後及時釋出新的列表版本,那麼Application Cache將帶來幾乎與線上模式無異的出色離線應用程式執行效果。
本地瀏覽器儲存在過去幾年中迎來了一輪重大變革。不同API及推薦專案所使用的多種多樣而且彼此相近的名稱讓我們很難弄清哪些可以繼續使用、而哪些應該及時淘汰。總而言之,瀏覽器資料儲存領域擁有多種不同方式可供選擇,而且每一種都有非常充分的存在價值。
無論如何,開發人員們努力通過cookies向伺服器傳送簡單的小型名-值對的時代已經結束。今天,我們擁有更多優秀的方案可供使用。
相關文章
- HTML5的五種客戶端離線儲存方案HTML客戶端
- HTML5 Web 客戶端五種離線儲存方式彙總HTMLWeb客戶端
- 客戶端儲存筆記客戶端筆記
- 客戶端儲存那些事客戶端
- 客戶端資料儲存概述客戶端
- 《客戶端儲存技術》總結客戶端
- MySQL client客戶端的四種連線方式MySqlclient客戶端
- HT for Web嵌入QtWebKit的客戶端解決方案QTWebKit客戶端
- 《客戶端儲存技術》讀後感客戶端
- 在客戶端儲存對EJB的遠端呼叫是否可行?客戶端
- 萌新必看——10種客戶端儲存哪家強,一文讀盡!客戶端
- 10種相親交友原始碼客戶端儲存方式,各有優缺點原始碼客戶端
- Web端與Client客戶端資料互動方案選擇Webclient客戶端
- 超越 Cookie:當今的客戶端資料儲存技術Cookie客戶端
- 客戶端(瀏覽器端)資料儲存技術概覽客戶端瀏覽器
- 表格儲存技術方案實踐及客戶案例分享
- HTML5離線應用與客戶端儲存HTML客戶端
- Spring 客戶端 IP 地址獲取及儲存細節Spring客戶端
- Asp.net直接儲存(下載)檔案到客戶端ASP.NET客戶端
- 【物件儲存】Minio本地執行和 golang客戶端基本操作物件Golang客戶端
- 求救!!關於Web Service客戶端的程式,Web客戶端
- 使用多種客戶端消費WCF RestFul服務(四)——Jquery篇客戶端RESTjQuery
- GRpc新增客戶端的五種方式RPC客戶端
- 技術週刊(2019-01-14 客戶端儲存 )客戶端
- 環信3.0ios客戶端的整合(四)iOS客戶端
- OSSEC服務端配置客戶端批次部署方案服務端客戶端
- 客戶端本地儲存的比較及使用window.name資料傳輸客戶端
- MQTT X Web:線上的 MQTT 5.0 客戶端工具MQQTWeb客戶端
- Slack使用React重寫Web客戶端ReactWeb客戶端
- Web客戶端安全性最佳實踐Web客戶端
- MySQL2:四種MySQL儲存引擎MySql儲存引擎
- 蘇寧影片雲直播客戶端的最佳化方案客戶端
- 客戶端影片渲染目前最理想的解決方案客戶端
- 瀏覽器有幾種儲存機制?講一講:Storage for the Web瀏覽器Web
- web端文字轉語音的幾種方案Web
- Node.js 使用http客戶端向網站請求資料並儲存Node.jsHTTP客戶端網站
- Redis 設計與實現 (四)--事件、客戶端Redis事件客戶端
- 解決cookies儲存中文報錯問題Cookie