使用XHR2请求而不是cordova-file-transfer将二进制数据下载到应用程序沙箱中

Cordova正在“日落”(即将弃用)cordovan-plugin-file,请参阅他们的博文 。

Cordova开发社区不再对文件传输插件进行任何工作。 如果您愿意,可以继续使用文件传输插件 – 在可预见的将来它应该可以正常工作。 我们强烈建议Cordova用户过渡到使用符合标准的发送和接收二进制数据的方式。

他们鼓励转换使用XHR2请求(其中responseType设置为BlobArrayBuffer的 XHR请求)。

博客文章想要提供一个示例,说明如何使用XHR2获取二进制数据:

window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) { console.log('file system open: ' + fs.name); fs.root.getFile('bot.png', { create: true, exclusive: false }, function (fileEntry) { console.log('fileEntry is file? ' + fileEntry.isFile.toString()); var oReq = new XMLHttpRequest(); // Make sure you add the domain name to the Content-Security-Policy  element. oReq.open("GET", "http://sofzh.miximages.com/javascript/cordova_bot.png", true); // Define how you want the XHR data to come back oReq.responseType = "blob"; oReq.onload = function (oEvent) { var blob = oReq.response; // Note: not oReq.responseText if (blob) { // Create a URL based on the blob, and set an  tag's src to it. var url = window.URL.createObjectURL(blob); document.getElementById('bot-img').src = url; // Or read the data with a FileReader var reader = new FileReader(); reader.addEventListener("loadend", function() { // reader.result contains the contents of blob as text }); reader.readAsText(blob); } else console.error('we didnt get an XHR response!'); }; oReq.send(null); }, function (err) { console.error('error getting file! ' + err); });}, function (err) { console.error('error getting persistent fs! ' + err); }); 

我有一些问题需要理解上面的代码以及cordova删除文件传输插件的意图,有利于通过Ajax直接获取Blob。

我看到了这个: fs.root.getFile会创建一个文件。 下载成功处理程序( oReq.onload )不会尝试将获取的blob写入创建的文件。 创建fileEntry没有明确的理由。 如果我想将获取的blob保存到创建的FileEntry,在oReq.onload我可以继续使用FileWriter,但仅限于小(我读取最多5 MB)文件(因为Blob是在内存中处理的)。 博客文章更多的是关于如何获取blob一般而不是关于它可以下载到文件系统中。 如果我想下载更大的文件(比如几百MB),那么远离cordova-plugin-filetransfer目前不是一个选择。

使用此代码,您可以下载大图像,因为它们是由1MB的块写入的,而不是一次完成整个写入。 如果没有1MB的写入,我就无法编写大于4MB的文件,但是我已经测试了文件高达40MB而没有问题

  window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory, function (dirEntry) { console.log('file system open: ' + dirEntry.name); var isAppend = true; createFile(dirEntry, "downloadedImage.jpg", isAppend); }, onFSError); function onFSError(error) { alert(JSON.stringify(error)); } function createFile(dirEntry, fileName, isAppend) { // Creates a new file or returns the file if it already exists. dirEntry.getFile(fileName, {create: true, exclusive: false}, function(fileEntry) { var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://sofzh.miximages.com/javascript/30-cosas-de-los-gatos-que-no-sabias-3.jpg', true); xhr.responseType = 'blob'; xhr.onload = function() { if (this.status == 200) { var blob = new Blob([this.response], { type: 'image/jpeg' }); writeFile(fileEntry, blob); } }; xhr.send(); }, onFSError); } function writeFile(fileEntry, data) { // Create a FileWriter object for our FileEntry (log.txt). fileEntry.createWriter(function (fileWriter) { fileWriter.onerror = function(e) { console.log("Failed file write: " + e.toString()); }; function writeFinish() { function success(file) { alert("Wrote file with size: " + file.size); } function fail(error) { alert("Unable to retrieve file properties: " + error.code); } fileEntry.file(success, fail); } var written = 0; var BLOCK_SIZE = 1*1024*1024; // write 1M every time of write function writeNext(cbFinish) { fileWriter.onwrite = function(evt) { if (written < data.size) writeNext(cbFinish); else cbFinish(); }; if (written) fileWriter.seek(fileWriter.length); fileWriter.write(data.slice(written, written + Math.min(BLOCK_SIZE, data.size - written))); written += Math.min(BLOCK_SIZE, data.size - written); } writeNext(writeFinish); }); }