关闭

在本地存储localStorage/sessionStorage中保存图片和文件(真的不适合保存文件图片大数据)

323人阅读 评论(0) 收藏 举报
分类:

localStorage支持还算广泛,ie8都有支持,存储量多数≈5M,也还可以,但是要是存储图片和文件,感觉就有些捉襟见肘,不过如有需要还是了解一下这方面的技术比较好。 
译文来自:http://w3ctech.com/p/1061,下面是译文的正文内容,关于如何存储图片和文件到本地存储。 

原文地址: http://hacks.mozilla.org/2012/02/saving-images-and-files-in-localstorage/

你可能已经对本地存储有所了解,本地存储在浏览器中快速存储数据的时候特别强大,并且已经在浏览器中存在多时。但是如何才能在本地存储中保存文件呢?

首先,推荐你先阅读 Storing images and files in IndexedDB 。

使用JSON实现强大的本地存储控制

首先,我们先了解一些基本的本地存储相关的知识。你可以使用键值对的方式往本地存储中存储数据,就像这样:

localStorage.setItem("name", "Robert");

而从本地存储中读取数据的方式如下:

localStorage.getItem("name");

这样的存取方式非常不错,而且最多可以存储5M的数据,给你更多选择的空间。但是由于本地存储是基于字符串的存储,存储一串没有结构的字符串并不是一个理想的选择。因此,我们可以利用浏览器中原生的JSON支持来将JavaScript对象转化成字符串,从而保存到本地数据中,在读取的时候也可以将其转换回JavaScript对象。

图片的存储

我们的想法是做到将已经当前页面中已缓存的图片保存到本地存储中。不过就像我们之前已经确定的,本地存储只支持字符串的存取,那么我们要做的就是将图片转换成 Data URI 。其中一种实现方式就是用canvas元素来加载图片。然后你可以以Data URI的形式从canvas中读取出当前展示的内容。

让我们看一个例子。

//当图片加载完成的时候触发回调函数
elephant.addEventListener("load", function () {
 var imgCanvas = document.createElement("canvas"),
 imgContext = imgCanvas.getContext("2d");
// 确保canvas元素的大小和图片尺寸一致
imgCanvas.width = elephant.width;
imgCanvas.height = elephant.height;

// 渲染图片到canvas中
imgContext.drawImage(elephant, 0, 0, elephant.width, elephant.height);

// 用data url的形式取出
var imgAsDataURL = imgCanvas.toDataURL("image/png");

// 保存到本地存储中
try {
localStorage.setItem("elephant", imgAsDataURL);
}
catch (e) {
console.log("Storage failed: " + e);
}
}, false);

如果我们想要考虑地更长远一些,那么还可以利用JavaScript对象并做一些数据检查。在这个例子中,第一次我们从服务端读取图片,之后每一次页面加载时,我们就可以直接从本地存储中读取已读取过的图片。

HTML部分

<figure>
 <img id="elephant" src="about:blank" alt="A close up of an elephant">
 <noscript>
 <img src="elephant.png" alt="A close up of an elephant">
 </noscript>
 <figcaption>A mighty big elephant, and mighty close too!</figcaption>
</figure>

JavaScript部分

//在本地存储中保存图片
var storageFiles = JSON.parse(localStorage.getItem("storageFiles")) || {},
 elephant = document.getElementById("elephant"),
 storageFilesDate = storageFiles.date,
 date = new Date(),
 todaysDate = (date.getMonth() + 1).toString() + date.getDate().toString();
// 检查数据,如果不存在或者数据过期,则创建一个本地存储
if (typeof storageFilesDate === "undefined" || storageFilesDate < todaysDate) {
 // 图片加载完成后执行
 elephant.addEventListener("load", function () {
 var imgCanvas = document.createElement("canvas"),
 imgContext = imgCanvas.getContext("2d");
// 确保canvas尺寸和图片一致
 imgCanvas.width = elephant.width;
 imgCanvas.height = elephant.height;
// 在canvas中绘制图片
 imgContext.drawImage(elephant, 0, 0, elephant.width, elephant.height);
// 将图片保存为Data URI
 storageFiles.elephant = imgCanvas.toDataURL("image/png");
storageFiles.date = todaysDate;
// 将JSON保存到本地存储中
try {
localStorage.setItem("storageFiles", JSON.stringify(storageFiles));
}
catch (e) {
console.log("Storage failed: " + e);
}
}, false);
// 设置图片
elephant.setAttribute("src", "elephant.png");
}
else {
// Use image from localStorage
elephant.setAttribute("src", storageFiles.elephant);
}

注意:此处需要注意本地存储的容量,最好使用try…catch来控制异常。

保存任意格式的文件

使用canvas将图片转换成Data URI并保存到本地存储中的方式非常好,但是如果我们希望能找到一个可以保存任意格式文件的方式。

那么,这个过程就显的比较有趣了,我们需要用到:

  • XMLHttpRequest Level 2
  • BlobBuilder (提供接口来构建Blob对象,Blob对象是BLOB (binary large object),二进制大对象,是一个可以存储二进制文件的容器。在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型。BLOB是一个大文件,典型的BLOB是一张图片或一个声音文件,由于它们的尺寸,必须使用特殊的方式来处理(例如:上传、下载或者存放到一个数据库)。)
  • FileReader

基本方法是:

  1. 用XMLHttpRequest请求文件,然后将响应头设置为”arraybuffer”。
  2. 将返回数据存放到BlobBuilder中
  3. 获取blob,也就是文件内容
  4. 使用FileReader对象读取文件并加载到文件中,最后保存到本地存储。
// 获取文件
var rhinoStorage = localStorage.getItem("rhino"),
 rhino = document.getElementById("rhino");
if (rhinoStorage) {
 //如果已经存在则直接重用已保存的数据
 rhino.setAttribute("src", rhinoStorage);
}
else {
 // 创建XHR, BlobBuilder 和FileReader 对象
 var xhr = new XMLHttpRequest(),
 blobBuilder = new (window.BlobBuilder || window.MozBlobBuilder || window.WebKitBlobBuilder || window.OBlobBuilder || window.msBlobBuilder),
 blob,
 fileReader = new FileReader();
 xhr.open("GET", "rhino.png", true);
 //将响应头类型设置为“arraybuffer”,也可以使用"blob",这样就不需要使用BlobBuilder来构建数据,但是"blob"的支持程度有限。
 xhr.responseType = "arraybuffer";
 xhr.addEventListener("load", function () {
 if (xhr.status === 200) {
 // 将响应数据放入blobBuilder中
 blobBuilder.append(xhr.response);
 // 用文件类型创建blob对象
 blob = blobBuilder.getBlob("image/png");
 // 由于Chrome不支持用addEventListener监听FileReader对象的事件,所以需要用onload
 fileReader.onload = function (evt) {
 // 用Data URI的格式读取文件内容
 var result = evt.target.result;
 // 将图片的src指向Data URI
 rhino.setAttribute("src", result);
 //保存到本地存储中
 try {
 localStorage.setItem("rhino", result);
 }
 catch (e) {
 console.log("Storage failed: " + e);
 }
 };
 // 以Data URI的形式加载blob
 fileReader.readAsDataURL(blob);
 }
 }, false);
 // 发送异步请求
 xhr.send();
}

使用“blob”作为响应头类型

在上面的例子中,我们使用的是“arraybuffer”作为响应头类型,然后使用BlobBuilder来创建可以由FileReader读取的数据。然而,”blob”作为响应头类型后,会直接返回一个blob对象,从而可以直接由FileReader读取。上面的例子可以改成这样:

// Getting a file through XMLHttpRequest as an arraybuffer and creating a Blob
var rhinoStorage = localStorage.getItem("rhino"),
 rhino = document.getElementById("rhino");
if (rhinoStorage) {
 // Reuse existing Data URL from localStorage
 rhino.setAttribute("src", rhinoStorage);
}
else {
 // Create XHR, BlobBuilder and FileReader objects
 var xhr = new XMLHttpRequest(),
 fileReader = new FileReader();
 xhr.open("GET", "rhino.png", true);
 // Set the responseType to arraybuffer. "blob" is an option too, rendering BlobBuilder unnecessary, but the support for "blob" is not widespread enough yet
 xhr.responseType = "blob";
 xhr.addEventListener("load", function () {
 if (xhr.status === 200) {
 // onload needed since Google Chrome doesn't support addEventListener for FileReader
 fileReader.onload = function (evt) {
 // Read out file contents as a Data URL
 var result = evt.target.result;
 // Set image src to Data URL
 rhino.setAttribute("src", result);
 // Store Data URL in localStorage
 try {
 localStorage.setItem("rhino", result);
 }
 catch (e) {
 console.log("Storage failed: " + e);
 }
 };
 // Load blob as Data URL
 fileReader.readAsDataURL(xhr.response);
 }
 }, false);
 // Send XHR
 xhr.send();
}

浏览器支持情况

  • 本地存储——大部分主流浏览器都支持(在国外=。=), including IE8.
  • 原生的JSON支持——支持情况和本地存储类似
  • canvas元素——大部分主流浏览器都支持,从IE9开始
  • XMLHttpRequest Level 2—— Firefox,Google Chrome, Safari 5+ 并计划在IE10和Opera 12中实现
  • BlobBuilder——Firefox ,Google Chrome,并计划在IE10中实现. Safari和Opera情况不明.
  • FileReader——Firefox ,Google Chrome,Opera 11.1之后的版本, 计划在IE10中实现. Safari情况不明.
  • responseType “blob”——只在Firefox中支持. Google Chrome即将支持,IE10计划支持.  Safari和Opera情况不明。
0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

sessionStorage、localStorage如何存储数组与对象

sessionStorage和localStorage做为HTML5新特性,被广泛应用于客户端缓存技术。不过这个有个误区,两者虽然对存储的内容大小没有限制,但是存入的东西都被转换成了字符串,也就是说无法存入数组或者对象,就算存入了也会被转化为字符串。不过实际开发过程中 缓存的数据一般都是 数组或者j...
  • u011413061
  • u011413061
  • 2015-11-23 19:28
  • 26330

使用本地存储localStorage保存数据的todoList

ToDoList 帮你把要做的事情列出来,一项一项,类似思维导图。 最明显的好处是强迫自己整理出任务的每个部分,理顺后按部就班的完成,提高效率。 现在,我们来使用js来做一个todolist基本功能开始的构思是用一个input来输入要做的事情,按钮确定,然后添加的列表,单击列表里的项目,就会使该...
  • Chation_99
  • Chation_99
  • 2017-01-12 14:21
  • 1118

客户端储存的三种方式localStorage 、sessionStorage、Cookies

Web应用允许使用浏览器提供的API实现将数据存储到用户的电脑上。这种客户端存储相当于赋予了Web浏览器记忆功能。比方说,Web应用就可以用这种方式来“记住”用户的配置信息甚至是用户所有的状态信息,以便准确地“回忆”起用户上一次访问时候的状态。客户端存储遵循“同源策略”,因此不同站点的页面是无法互相...
  • donggx
  • donggx
  • 2016-12-30 15:31
  • 2488

HTML5 本地存储 localStorage、sessionStorage 的遍历、存储大小限制处理

HTML5 的本地存储 API 中的 localStorage 与 sessionStorage 在使用方法上是相同的,区别在于 sessionStorage 在关闭页面后即被清空,而 localStorage 则会一直保存。我们这里以 localStorage 为例,简要介绍下 HTML5 的本地...
  • cengjingcanghai123
  • cengjingcanghai123
  • 2015-11-09 12:21
  • 24492

HTML5的本地存储功能,使用localStorage

HTML文件内容: HTML5的本地存储功能,使用localStorage <!-- localStorage的存储位置在:C:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Default\...
  • mazhili1991
  • mazhili1991
  • 2016-12-05 18:22
  • 973

cookie、localStorage、sessionStorage的有效期和作用域问题

。。。。待续
  • atgwwx
  • atgwwx
  • 2013-11-14 22:15
  • 12452

Html5本地储存localStorage 之储存json数组

什么是html5本地储存localStorage : HTML5 提供了两种在客户端存储数据的新方法: 1.localStorage - 没有时间限制的数据存储 2.sessionStorage - 针对一个 session 的数据存储 之前,这些都是由 cookie 完成的...
  • yy211zhu
  • yy211zhu
  • 2016-12-10 15:13
  • 1127

WebView中你不知道的事localStorage

今天在开发项目的时候碰到一个怪事:本着以为开发webview都是简简单单的事情首先:实例化webview,启用JavaScript,接着再设置WebViewClientmWebView = (WebView) findViewById(R.id.webView);WebSettings settin...
  • u014059459
  • u014059459
  • 2016-01-20 16:50
  • 5258

H5笔记1-本地存储localStorage

localStorage是啥? 在很久很久以前,客户端存储信息用的都是cookie。但是cookie在存储空间上,有一些限制。 浏览器 cookie个数(每个域名) 单个cookie容量限制 Microsoft 50个 4KB左右(包括name、value和等号) Fir...
  • quanyechalaila
  • quanyechalaila
  • 2016-04-29 14:54
  • 1802

JS的本地保存localStorage、sessionStorage用法总结

JS的本地保存localStorage、sessionStorage用法总结
  • kerryqpw
  • kerryqpw
  • 2017-05-09 09:36
  • 2519