我正在尝试理解HTML5 API。 我正在设计Web应用程序,浏览器客户端需要从服务器下载多个文件;用户将对下载的文件和应用程序执行某些操作,而不是需要在用户上保存状态。我知道浏览器只能将这些文件保存到它的沙盒中,只要用户可以在第二次启动应用程序时检索这些文件就可以了。 我应该使用BlobBuilder还是FileSaver?我在这里有点迷失。
答案 0 :(得分:65)
我将向您展示如何使用XMLHttpRequest Level 2下载文件,并使用FileSystem API或FileSaver interface保存文件。
要下载文件,您将使用XMLHttpRequest Level 2(又名XHR2),它支持跨源请求,上传进度事件以及上载/下载二进制数据。在帖子“New Tricks in XMLHttpRequest2”中有大量使用XHR2的例子。
要将文件作为blob下载,您只需将responseType
指定为“blob”即可。您还可以使用“text”,“arraybuffer”或“document”类型。下面的函数会在url
中下载该文件并将其发送到success
回调:
function downloadFile(url, success) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = "blob";
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (success) success(xhr.response);
}
};
xhr.send(null);
}
success
回调将接收Blob实例作为参数,以后可以修改并保存和/或上传到服务器。
由于我可以使用网站points out,因此没有很多浏览器支持FileSystem API。对于Firefox there's an explanation缺乏支持。因此,您必须使用Chrome才能执行此操作。
首先,您必须请求存储空间,它可以是临时存储空间,也可以是持久存储空间。您可能希望拥有持久存储,在这种情况下,您将预先请求一个存储空间配额(some facts):
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.storageInfo = window.storageInfo || window.webkitStorageInfo;
// Request access to the file system
var fileSystem = null // DOMFileSystem instance
, fsType = PERSISTENT // PERSISTENT vs. TEMPORARY storage
, fsSize = 10 * 1024 * 1024 // size (bytes) of needed space
;
window.storageInfo.requestQuota(fsType, fsSize, function(gb) {
window.requestFileSystem(fsType, gb, function(fs) {
fileSystem = fs;
}, errorHandler);
}, errorHandler);
现在您可以访问文件系统,可以保存和读取文件。下面的函数可以将指定路径中的blob保存到文件系统中:
function saveFile(data, path) {
if (!fileSystem) return;
fileSystem.root.getFile(path, {create: true}, function(fileEntry) {
fileEntry.createWriter(function(writer) {
writer.write(data);
}, errorHandler);
}, errorHandler);
}
通过它的路径读取文件:
function readFile(path, success) {
fileSystem.root.getFile(path, {}, function(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
if (success) success(this.result);
};
reader.readAsText(file);
}, errorHandler);
}, errorHandler);
}
除readAsText
方法外,根据FileReader API,您可以致电readAsArrayBuffer
和readAsDataURL
。
帖子“Saving Generated Files on Client-Side”很好地解释了此API的使用。某些浏览器可能需要FileSaver.js才能拥有saveAs
接口。
如果将它与downloadFile
函数一起使用,您可以使用以下内容:
downloadFile('image.png', function(blob) {
saveAs(blob, "image.png");
});
当然,如果用户可以将图像可视化,操纵它然后将其保存在驱动器中,那将更有意义。
只是为了实现这个例子:
function errorHandler(e) {
var msg = '';
switch (e.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = 'QUOTA_EXCEEDED_ERR';
break;
case FileError.NOT_FOUND_ERR:
msg = 'NOT_FOUND_ERR';
break;
case FileError.SECURITY_ERR:
msg = 'SECURITY_ERR';
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = 'INVALID_MODIFICATION_ERR';
break;
case FileError.INVALID_STATE_ERR:
msg = 'INVALID_STATE_ERR';
break;
default:
msg = 'Unknown Error';
break;
};
console.log('Error: ' + msg);
}
答案 1 :(得分:2)
如果您只支持HTML5浏览器,则可以下载"下载"你可以使用的属性。更多详情:http://updates.html5rocks.com/2011/08/Downloading-resources-in-HTML5-a-download
答案 2 :(得分:0)
我的诀窍就是简单地添加一个指向多次下载的“src”属性的IFRAME。服务器站点应该发送带有“disposition:attachment”标头的文件,然后客户端将尝试在本地存储该文件。唯一的“问题”是IFRAME将作为碎片保留在DOM树中,直到用户离开或重新加载页面。使IFRAME不可见(例如width = 0; height = 0;),你准备好了!所有浏览器。