我遇到需要在变量中存储文件信息(File
对象)的情况,但我首先需要JSON.stringify
它。这不适用于File
个对象:
> JSON.stringify(new File([], null))
« "{}"
所以我需要做的是,获取用户上传的文件,将其转换为普通对象,以字符串格式存储,然后再将其拉出JSON.parse
,然后将其转换回File
。将它转换为普通对象很简单,但是将它恢复到File
对象是我找不到任何方法可以实现的。
补充说明:
所以,让我们说我已将File
的属性复制到普通对象中:
{
"lastModified": 1443077616000,
"lastModifiedDate": "2015-09-24T06:53:36.000Z",
"name": "Action Items.zip",
"size": 3619135,
"type": "application/zip"
}
我只需将其转换回File
对象。
答案 0 :(得分:0)
基于此评论(How to convert a plain JavaScript object to a File object?),您只需要一个字符串
使用FileReader API将文件转换为DataURL
var fileReader = new FileReader();
// 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;
// do whatever with RESULT
// JSON or whatever
};
// Load blob (File inherits from BLOB) as Data URL
fileReader.readAsDataURL(blob);
使用此功能https://github.com/ebidel/filer.js/blob/master/src/filer.js#L131-L158 将DataURL转换回文件。
/**
* Creates and returns a blob from a data URL (either base64 encoded or not).
*
* @param {string} dataURL The data URL to convert.
* @return {Blob} A blob representing the array buffer data.
*/
dataURLToBlob: function(dataURL) {
var BASE64_MARKER = ';base64,';
if (dataURL.indexOf(BASE64_MARKER) == -1) {
var parts = dataURL.split(',');
var contentType = parts[0].split(':')[1];
var raw = decodeURIComponent(parts[1]);
return new Blob([raw], {
type: contentType
});
}
var parts = dataURL.split(BASE64_MARKER);
var contentType = parts[0].split(':')[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], {
type: contentType
});
}
(你可以在任何地方用文件替换Blob,因为文件继承自Blob)
以下是我如何获取用户删除的文件,将其转换为base64字符串,保存它(没有localStorage因为沙盒)以及稍后取回字符串并将其转换回文件的示例这是由用户发送的。 这不是你想要的吗?
var drop = document.getElementById('drop'),
transform = document.getElementById('transform');
drop.addEventListener('dragover', function (e) {
e.stopPropagation();
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
});
var originalFile = null;
drop.addEventListener('drop', function (e) {
e.preventDefault();
e.stopPropagation();
originalFile = event.dataTransfer.files[0];
console.log('originalFile', originalFile);
fileToURLData(originalFile);
}, false);
var storage = {};
function fileToURLData(file) {
var fileReader = new FileReader();
// 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;
/*localStorage.setItem('file-data', JSON.stringify({
dataURL: result,
name: file.name,
lastModified: file.lastModified,
lastModifiedDate: file.lastModifiedDate,
type: "image/jpeg"
}));*/
storage = JSON.stringify({
dataURL: result,
name: file.name,
lastModified: file.lastModified,
lastModifiedDate: file.lastModifiedDate,
type: "image/jpeg"
})
console.log('File dataURL',result);
// do whatever with RESULT
// JSON or whatever
transform.className = 'show';
drop.className = 'hide';
};
// Load blob (File inherits from BLOB) as Data URL
fileReader.readAsDataURL(file);
}
function dataURLToFile(dataURL, name, data) {
var BASE64_MARKER = ';base64,';
if (dataURL.indexOf(BASE64_MARKER) == -1) {
var parts = dataURL.split(',');
var raw = decodeURIComponent(parts[1]);
return new File([raw], name, data);
}
var parts = dataURL.split(BASE64_MARKER);
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new File([uInt8Array], name, data);
}
transform.addEventListener('click', function (e) {
e.preventDefault();
e.stopPropagation();
var fileData= JSON.parse(storage); //localStorage.getItem('file-data')),
dataURL = fileData['dataURL'],
name = fileData.name;
delete fileData.dataURL;
delete fileData.name;
console.log(dataURL, name, fileData);
var file = dataURLToFile(dataURL, name, fileData);
console.log('convertedFile', file);
console.log('originalFile', originalFile);
console.log('originalFile === convertedFile ? ', originalFile === file);
console.log('different files, same values');
alert('DATAURL HAS BEEN CONVERTED BACK TO FILE - SEE CONSOLE');
}, false);
html, html {
width: 100%;
height: 100%;
min-height: 500px;
text-align: center;
font-size: 50px;
}
#drop {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
color: #fff;
}
#drop.hide {
display: none;
}
#transform {
display: none;
}
#transform.show {
display: block;
}
<div id='drop'>DROP FILE HERE</div>
<button id='transform'>Transform back to file</div>