如何在本地存储中保存和还原File对象

pin*_*yid 39 javascript html5 local-storage

我有一个HTML5/javscript应用程序使用

<input type="file" accept="image/*;capture=camera" onchange="gotPhoto(this)">
Run Code Online (Sandbox Code Playgroud)

捕捉相机图像.由于我的应用程序希望脱机运行,如何将文件(https://developer.mozilla.org/en-US/docs/Web/API/File)对象保存在本地存储中,以便以后可以检索对于ajax上传?

我从使用中抓取文件对象...

function gotPhoto(element) { 
     var file = element.files[0];
     //I want to save 'file' to local storage here :-(
}
Run Code Online (Sandbox Code Playgroud)

我可以对对象进行Stringify并保存,但是当我恢复它时,它不再被识别为File对象,因此不能用于获取文件内容.

我有一种感觉它无法做到,但我愿意接受建议.

fwiw我的工作是在商店时读取文件内容并将全部内容保存到本地存储.这可以工作,但很快消耗本地存储,因为每个文件是1MB加上照片.

Jos*_*han 12

这是一个解决方法,我使用下面的代码.我知道你的编辑,你谈到localStorage,但我想分享我实际实现的解决方法.我喜欢将函数放在body上,这样即使之后通过AJAX添加了类,"change"命令仍然会触发事件.

看看我的例子:http://jsfiddle.net/x11joex11/9g8NN/

如果您运行两次JSFiddle示例,您将看到它记住图像.

我的方法确实使用jQuery.这种方法也证明了图像实际上是为了证明它有效.

HTML:

<input class="classhere" type="file" name="logo" id="logo" />
<div class="imagearea"></div>
Run Code Online (Sandbox Code Playgroud)

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.
    });
});
Run Code Online (Sandbox Code Playgroud)

此方法使用HTML5文件系统API来读取图像并将其放入新的javascript img对象中.这里的关键是readAsDataURL.如果使用chrome检查器,您会注意到图像以base64编码存储.

读者是异步的,这就是它使用回调函数onload的原因.因此,请确保需要图像的任何重要代码都在onLoad中,否则您可能会得到意外的结果.

  • 感谢您发布解决方法,我相信它将对人们有所帮助。我希望可以编辑您的答案以强调它是一种解决方法,而不是问题的答案,这是可以的。我一直在寻找一种方法来保存File对象,而无需对图像数据进行第二次复制。 (2认同)
  • @pinoyyid这是一个解决方法?它出什么问题了? (2认同)
  • 我特别希望保留文件*对象*,而不是文件*内容*。我的应用程序面向移动设备,因此图像已保存在图库中。我想存储对图库图像的引用,而不是使用本地存储制作第二个副本,并受到其附带的所有大小限制。 (2认同)

Geo*_*kis 9

您无法序列化文件API对象.

并不是它有助于解决具体问题,但是......虽然我没有使用过这个,如果你看一下这里似乎有一些方法(大多数浏览器还没有支持)将离线图像数据存储到某些文件中以后当用户在线时恢复它们(而不是使用localstorage)

  • 问题是页面/浏览器重新加载。如果用户卸载页面,我将丢失存储在内存中的所有内容。 (2认同)
  • 由于明显的安全风险,这是不可能的.如果允许将File对象作为字符串保存在本地存储中,您还可以修改该字符串,以便在用户不知道的情况下访问同一目录中的其他文件. (2认同)

The*_*ius 6

将其转换为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
Run Code Online (Sandbox Code Playgroud)

  • thx,但请再次阅读问题。我不想保存文件内容,我想保存File对象。 (2认同)