[英]How do I save and restore a File object in local storage
我有一個 HTML5/javscript 應用程序,它使用
<input type="file" accept="image/*;capture=camera" onchange="gotPhoto(this)">
捕捉相機圖像。 因為我的應用程序想要離線運行,我如何將文件( https://developer.mozilla.org/en-US/docs/Web/API/File )對象保存在本地存儲中,以便以后可以檢索它ajax 上傳?
我正在從 using ... 中獲取文件對象
function gotPhoto(element) {
var file = element.files[0];
//I want to save 'file' to local storage here :-(
}
我可以將對象字符串化並保存,但是當我恢復它時,它不再被識別為文件對象,因此不能用於抓取文件內容。
我覺得它做不到,但我願意接受建議。
FWIW 我的解決方法是在存儲時讀取文件內容並將全部內容保存到本地存儲。 這可行,但很快就會消耗本地存儲,因為每個文件都是 1MB 以上的照片。
您不能序列化文件 API 對象。
並不是說它有助於解決具體問題,但是......雖然我沒有使用過這個,但如果你看這篇文章,似乎有一些方法(雖然大多數瀏覽器還不支持)將離線圖像數據存儲到一些文件以便在用戶在線時恢復它們(而不是使用localStorage)
將其轉換為base64,然后保存。
function gotPhoto(element) {
var file = element.files[0];
var reader = new FileReader()
reader.onload = function(base64) {
localStorage["file"] = base64;
}
reader.readAsDataURL(file);
}
// Saved to localstorage
function getPhoto() {
var base64 = localStorage["file"];
var base64Parts = base64.split(",");
var fileFormat = base64Parts[0].split(";")[1];
var fileContent = base64Parts[1];
var file = new File([fileContent], "file name here", {type: fileFormat});
return file;
}
// Retreived file object
這是我使用下面的代碼的一種解決方法。 我知道您在編輯時談到了 localStorage,但我想分享我是如何實際實施該解決方法的。 我喜歡將函數放在主體上,這樣即使之后通過 AJAX 添加了類,“更改”命令仍然會觸發事件。
在這里查看我的示例:http: //jsfiddle.net/x11joex11/9g8NN/
如果您兩次運行 JSFiddle 示例,您將看到它記住了圖像。
我的方法確實使用了 jQuery。 這種方法還演示了圖像實際上可以證明它有效。
HTML:
<input class="classhere" type="file" name="logo" id="logo" />
<div class="imagearea"></div>
JS:
$(document).ready(function(){
//You might want to do if check to see if localstorage set for theImage here
var img = new Image();
img.src = localStorage.theImage;
$('.imagearea').html(img);
$("body").on("change",".classhere",function(){
//Equivalent of getElementById
var fileInput = $(this)[0];//returns a HTML DOM object by putting the [0] since it's really an associative array.
var file = fileInput.files[0]; //there is only '1' file since they are not multiple type.
var reader = new FileReader();
reader.onload = function(e) {
// Create a new image.
var img = new Image();
img.src = reader.result;
localStorage.theImage = reader.result; //stores the image to localStorage
$(".imagearea").html(img);
}
reader.readAsDataURL(file);//attempts to read the file in question.
});
});
這種方法使用 HTML5 文件系統 API 來讀取圖像並將其放入新的 javascript img 對象中。 這里的關鍵是 readAsDataURL。 如果您使用 chrome 檢查器,您會注意到圖像以 base64 編碼存儲。
讀者是異步的,這就是它使用回調函數onload的原因。 因此,請確保任何需要圖像的重要代碼都在 onLoad 中,否則您可能會得到意想不到的結果。
你可以使用這個庫:
https://github.com/carlo/jquery-base64
然后做類似的事情:
//Set file
var baseFile = $.base64.encode(fileObject);
window.localStorage.setItem("file",basefile);
//get file
var outFile = window.localStorage.getItem("file");
另一種解決方案是使用 json(我更喜歡這種方法),使用: http ://code.google.com/p/jquery-json/
//Set file
window.localStorage.setItem("file",$.toJSON(fileobject));
//get file
var outFile = $.evalJSON(window.localStorage.getItem("file"));
我認為沒有直接的方法可以將字符串化,然后將字符串對象反序列化為您感興趣的對象。 但作為一種解決方法,您可以將圖像路徑存儲在本地存儲中,並通過檢索圖像的 URL 來加載圖像。 優點是,您永遠不會用完存儲空間,並且可以在那里存儲 1000 倍以上的文件。將圖像或任何其他文件作為字符串保存在本地存儲中絕不是一個明智的決定。
在全局范圍內創建對象
exp: var attmap = new Object();
完成文件選擇后,將文件放入 attmap 變量中,如下所示,
attmap[file.name] = attachmentBody;
JSON.stringify(attmap)
然后您可以通過輸入隱藏等將其發送到控制器,並在反序列化后使用它。
(Map<String, String>)JSON.deserialize(attachments, Map<String,String>.class);
您可以在 for 循環等中使用這些值創建文件。
EncodingUtil.base64Decode(CurrentMapValue);
僅供參考:此解決方案還將涵蓋多個文件選擇
你可以這樣做:
// fileObj = new File(); from file input
const buffer = Buffer.from(await new Response(fileObj).arrayBuffer());
const dataUrl = `data:${fileObj.type};base64,${buffer.toString("base64")}`;
localStorage.setItem('dataUrl', dataUrl);
那么你可以這樣做:
document.getElementById('image').src = localStorage.getItem('dataUrl');
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.