一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

在本地存儲localStorage中保存圖片和文件(任意格式)

 宋曉斌987 2015-10-16

localStorage支持還算廣泛,ie8都有支持,存儲量多數(shù)≈5M,也還可以,但是要是存儲圖片和文件,感覺就有些捉襟見肘,不過如有需要還是了解一下這方面的技術(shù)比較好。 
譯文來自:http:///p/1061,下面是譯文的正文內(nèi)容,關(guān)于如何存儲圖片和文件到本地存儲。 

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

你可能已經(jīng)對本地存儲有所了解,本地存儲在瀏覽器中快速存儲數(shù)據(jù)的時候特別強大,并且已經(jīng)在瀏覽器中存在多時。但是如何才能在本地存儲中保存文件呢?

首先,推薦你先閱讀 Storing images and files in IndexedDB 

使用JSON實現(xiàn)強大的本地存儲控制

首先,我們先了解一些基本的本地存儲相關(guān)的知識。你可以使用鍵值對的方式往本地存儲中存儲數(shù)據(jù),就像這樣:

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

而從本地存儲中讀取數(shù)據(jù)的方式如下:

localStorage.getItem("name");

這樣的存取方式非常不錯,而且最多可以存儲5M的數(shù)據(jù),給你更多選擇的空間。但是由于本地存儲是基于字符串的存儲,存儲一串沒有結(jié)構(gòu)的字符串并不是一個理想的選擇。因此,我們可以利用瀏覽器中原生的JSON支持來將JavaScript對象轉(zhuǎn)化成字符串,從而保存到本地數(shù)據(jù)中,在讀取的時候也可以將其轉(zhuǎn)換回JavaScript對象。

圖片的存儲

我們的想法是做到將已經(jīng)當前頁面中已緩存的圖片保存到本地存儲中。不過就像我們之前已經(jīng)確定的,本地存儲只支持字符串的存取,那么我們要做的就是將圖片轉(zhuǎn)換成 Data URI 。其中一種實現(xiàn)方式就是用canvas元素來加載圖片。然后你可以以Data URI的形式從canvas中讀取出當前展示的內(nèi)容。

讓我們看一個例子。

//當圖片加載完成的時候觸發(fā)回調(diào)函數(shù)
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對象并做一些數(shù)據(jù)檢查。在這個例子中,第一次我們從服務(wù)端讀取圖片,之后每一次頁面加載時,我們就可以直接從本地存儲中讀取已讀取過的圖片。

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();
// 檢查數(shù)據(jù),如果不存在或者數(shù)據(jù)過期,則創(chuàng)建一個本地存儲
if (typeof storageFilesDate === "undefined" || storageFilesDate < todaysDate) {
 // 圖片加載完成后執(zhí)行
 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);
// 設(shè)置圖片
elephant.setAttribute("src", "elephant.png");
}
else {
// Use image from localStorage
elephant.setAttribute("src", storageFiles.elephant);
}

注意:此處需要注意本地存儲的容量,最好使用try…catch來控制異常。

保存任意格式的文件

使用canvas將圖片轉(zhuǎn)換成Data URI并保存到本地存儲中的方式非常好,但是如果我們希望能找到一個可以保存任意格式文件的方式。

那么,這個過程就顯的比較有趣了,我們需要用到:

  • XMLHttpRequest Level 2
  • BlobBuilder (提供接口來構(gòu)建Blob對象,Blob對象是BLOB (binary large object),二進制大對象,是一個可以存儲二進制文件的容器。在計算機中,BLOB常常是數(shù)據(jù)庫中用來存儲二進制文件的字段類型。BLOB是一個大文件,典型的BLOB是一張圖片或一個聲音文件,由于它們的尺寸,必須使用特殊的方式來處理(例如:上傳、下載或者存放到一個數(shù)據(jù)庫)。)
  • FileReader

基本方法是:

  1. 用XMLHttpRequest請求文件,然后將響應(yīng)頭設(shè)置為”arraybuffer”。
  2. 將返回數(shù)據(jù)存放到BlobBuilder中
  3. 獲取blob,也就是文件內(nèi)容
  4. 使用FileReader對象讀取文件并加載到文件中,最后保存到本地存儲。
// 獲取文件
var rhinoStorage = localStorage.getItem("rhino"),
 rhino = document.getElementById("rhino");
if (rhinoStorage) {
 //如果已經(jīng)存在則直接重用已保存的數(shù)據(jù)
 rhino.setAttribute("src", rhinoStorage);
}
else {
 // 創(chuàng)建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);
 //將響應(yīng)頭類型設(shè)置為“arraybuffer”,也可以使用"blob",這樣就不需要使用BlobBuilder來構(gòu)建數(shù)據(jù),但是"blob"的支持程度有限。
 xhr.responseType = "arraybuffer";
 xhr.addEventListener("load", function () {
 if (xhr.status === 200) {
 // 將響應(yīng)數(shù)據(jù)放入blobBuilder中
 blobBuilder.append(xhr.response);
 // 用文件類型創(chuàng)建blob對象
 blob = blobBuilder.getBlob("image/png");
 // 由于Chrome不支持用addEventListener監(jiān)聽FileReader對象的事件,所以需要用onload
 fileReader.onload = function (evt) {
 // 用Data URI的格式讀取文件內(nèi)容
 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);
 // 發(fā)送異步請求
 xhr.send();
}

使用“blob”作為響應(yīng)頭類型

在上面的例子中,我們使用的是“arraybuffer”作為響應(yīng)頭類型,然后使用BlobBuilder來創(chuàng)建可以由FileReader讀取的數(shù)據(jù)。然而,”blob”作為響應(yīng)頭類型后,會直接返回一個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中實現(xiàn)
  • BlobBuilder——Firefox ,Google Chrome,并計劃在IE10中實現(xiàn). Safari和Opera情況不明.
  • FileReader——Firefox ,Google Chrome,Opera 11.1之后的版本, 計劃在IE10中實現(xiàn). Safari情況不明.
  • responseType “blob”——只在Firefox中支持. Google Chrome即將支持,IE10計劃支持.  Safari和Opera情況不明。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    国产午夜精品福利免费不| 人妻偷人精品一区二区三区不卡 | 少妇激情在线免费观看| 中文字幕精品一区二区三| 日本一级特黄大片国产| 亚洲一区二区三区精选| 偷拍偷窥女厕一区二区视频| 黄色国产自拍在线观看| 亚洲人妻av中文字幕| 91久久精品在这里色伊人| 国产欧美日产久久婷婷| 亚洲中文字幕三区四区| 91香蕉视频精品在线看| 国产超薄黑色肉色丝袜| 日本久久精品在线观看| 黑丝国产精品一区二区| 视频一区二区 国产精品| 五月婷婷六月丁香亚洲| 日本欧美一区二区三区在线播| 亚洲综合激情另类专区老铁性| 尹人大香蕉中文在线播放| 日韩国产亚洲欧美另类 | 国产成人综合亚洲欧美日韩| 大香蕉精品视频一区二区| 91亚洲国产成人久久| 国产内射一级二级三级| 日本亚洲精品在线观看| 女厕偷窥一区二区三区在线| 国产精品免费福利在线| 色丁香之五月婷婷开心| 欧美日韩国产福利在线观看| 久久精品中文扫妇内射| 国产精品久久精品毛片| 久久热在线视频免费观看| 99久热只有精品视频免费看| 九九热这里有精品20| 欧美在线观看视频三区| 少妇人妻无一区二区三区| 亚洲欧美日韩精品永久| 色狠狠一区二区三区香蕉蜜桃| 青青操视频在线播放免费|