首页 > 代码库 > Web - 客户端存储的几种方式

Web - 客户端存储的几种方式

客户端存储主要方便一些APP离线使用。今天就来说说客户端存储的方法有多少?
说在最前面的一句:所有的客户端存储都有一个原则:读写的数据必须要同域

1 Cookie

Cookie是一项很老的技术的,就是因为它老,所以兼容性还是不错的。常见的JS操作Cookie的代码如下:

function setCookie(c_name,value,expiredays){  var exdate=new Date()  exdate.setDate(exdate.getDate()+expiredays)  document.cookie=c_name+ "=" +escape(value)+((expiredays==null) ? "" : ";expires="+exdate.toGMTString())}function getCookie(c_name){if (document.cookie.length>0)  {  c_start=document.cookie.indexOf(c_name + "=")  if (c_start!=-1)    {     c_start=c_start + c_name.length+1     c_end=document.cookie.indexOf(";",c_start)    if (c_end==-1) c_end=document.cookie.length    return unescape(document.cookie.substring(c_start,c_end))    }   }return ""}

代码是从W3school那里扣过来的,大半夜了我也就不知道写了,请原谅我。
使用Cookie作为本地存储优点:兼容性好,缺点:操作繁琐,只能存简单的数据,还会过期,站点设置httponly的话,JS就不无法操作Cookie了

2 Web Storage

WebStorage是HTML5中为WebApplication提供一种存储的API,目前主流的新版本的浏览器都支持,当然IE789你就没有办法了。WebStorage主要分成localStorage和sessionStorage两种。

sessionStorage 是个全局对象,它维护着在页面会话(page session)期间有效的存储空间。只要浏览器开着,页面会话周期就会一直持续。当页面重新载入(reload)或者被恢复(restores)时,页面会话也是一直存在的。每在新标签或者新窗口中打开一个新页面,都会初始化一个新的会话。

localStorage也是一个全局变量,它的生命周期比sessionStorage长。localStorage和sessionStorage都继承自Storage因此它们的用法相同。

interface Storage {  readonly attribute unsigned long length;  [IndexGetter] DOMString key(in unsigned long index);  [NameGetter] DOMString getItem(in DOMString key);  [NameSetter] void setItem(in DOMString key, in DOMString data);  [NameDeleter] void removeItem(in DOMString key);  void clear();};
// 保存数据到当前会话的存储空间sessionStorage.setItem("username", "John");// 访问数据alert( "username = " + sessionStorage.getItem("username"));

WebStorage的优点:使用简单方便,缺点:IE有些版本不支持,不能存复杂的对象,必须先转化成JSON字符串,没有索引搜索效率不高,只能同步读写操作,当写入的数据比较大时可能造成JS引擎堵塞。

3 IndexedDB

IndexedDB是一种基于Javascript对象继承的数据库,它支持事务,同时支持异步和同步读写。IndexedDB中可以存入对象,当然对象要能够结构化克隆(structured clone),同时它还提供索引功能,极大地提高了搜索的效率。通常来说IndexedDB的大小是没有限制,当大小超过50MB的时候,浏览器会弹出对话框来询问用户是否增加数据的大小。

var request = window.indexedDB.open("CandyDB",                                    "My candy store database");request.onsuccess = function(event) {  var db = event.result;  if (db.version != "1") {    // User‘s first visit, initialize database.    var createdObjectStoreCount = 0;    var objectStores = [      { name: "kids", keyPath: "id", autoIncrement: true },      { name: "candy", keyPath: "id", autoIncrement: true },      { name: "candySales", keyPath: "", autoIncrement: true }    ];     function objectStoreCreated(event) {      if (++createdObjectStoreCount == objectStores.length) {        db.setVersion("1").onsuccess = function(event) {          loadData(db);        };      }    }     for (var index = 0; index < objectStores.length; index++) {      var params = objectStores[index];      request = db.createObjectStore(params.name, params.keyPath,                                     params.autoIncrement);      request.onsuccess = objectStoreCreated;    }  }  else {    // User has been here before, no initialization required.    loadData(db);  }};var kids = [  { name: "Anna" },  { name: "Betty" },  { name: "Christine" }]; var request = window.indexedDB.open("CandyDB",                                    "My candy store database");request.onsuccess = function(event) {  var objectStore = event.result.objectStore("kids");  for (var index = 0; index < kids.length; index++) {    var kid = kids[index];    objectStore.add(kid).onsuccess = function(event) {      document.getElementById("display").textContent =        "Saved record for " + kid.name + " with id " + event.result;    };  }};

优点:支持事务,支持索引,可以存入对象,效率也不错。缺点:使用有些麻烦,上手需要一定时间

4 FileAPI

在最新版的MDN和w3c中FileAPI相关的文档只看到了FileReader相关介绍,这个API可以结合File表单和Formdata 从而实现异步上传文件。因为没有FileWriter相关文档说明,我们这里暂时认为FileAPI不能实现客户端存储这个要求

function startRead() {    // obtain input element through DOM     var file = document.getElementById(‘file‘).files[0];  if(file){    getAsText(file);  }}function getAsText(readFile) {          var reader = new FileReader();    // Read file into memory as UTF-16        reader.readAsText(readFile, "UTF-16");    // Handle progress, success, and errors  reader.onprogress = updateProgress;  reader.onload = loaded;  reader.onerror = errorHandler;}function updateProgress(evt) {  if (evt.lengthComputable) {    // evt.loaded and evt.total are ProgressEvent properties    var loaded = (evt.loaded / evt.total);    if (loaded < 1) {      // Increase the prog bar length      // style.width = (loaded * 200) + "px";    }  }}function loaded(evt) {    // Obtain the read file data      var fileString = evt.target.result;  // Handle UTF-16 file dump  if(utils.regexp.isChinese(fileString)) {    //Chinese Characters + Name validation  }  else {    // run other charset test  }  // xhr.send(fileString)     }function errorHandler(evt) {  if(evt.target.error.name == "NotReadableError") {    // The file could not be read  }}

5 参考

  1. https://developer.mozilla.org/zh-CN/docs/Web/Guide/API/DOM/Storage/Storage
  2. https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
  3. https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/The_structured_clone_algorithm
  4. https://developer.mozilla.org/en-US/docs/Web/API/FileReader
  5. http://www.w3.org/TR/FileAPI/
  6. http://www.w3.org/TR/file-writer-api/

Web - 客户端存储的几种方式