使用XHR2请求而不是cordova-file-transfer将二进制数据下载到应用程序沙箱中 [英] Download binary data into the app sandbox using XHR2 request instead of cordova-file-transfer

查看:230
本文介绍了使用XHR2请求而不是cordova-file-transfer将二进制数据下载到应用程序沙箱中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Cordova正在日落(即将弃用)cordovan-plugin-file,请参阅他们的博客帖子

Cordova is "sunsetting" (going to deprecate) cordovan-plugin-file, see their blogpost.


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

No more work will be done on the file-transfer plugin by the Cordova development community. You can continue to use the file-transfer plugin if you wish - it should work fine as-is for the foreseeable future. We highly suggest Cordova users transition to using the standards-compliant way of sending and receiving binary data.

他们鼓励转换为使用XHR2请求(XHR请求,其中 responseType 设置为 Blob ArrayBuffer

They are encouraging a transition to use XHR2 requests (XHR Requests where the responseType is set to Blob or ArrayBuffer.

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

The blog post wants to provide an example how binary data can be fetched using 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 <meta> element.
    oReq.open("GET", "http://cordova.apache.org/static/img/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 <img> 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的意图删除file-tranfer插件,转而使用
直接通过Ajax获取Blob。


I have some issues understanding the code above and the intention of cordova to drop the file-tranfer plugin in favour of directly fetching the Blobs via Ajax.

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

Am I seeing this right: fs.root.getFile creates a file. The download success handler (oReq.onload) does not attempt to write the fetched blob to the created file. There is no clear reason why the fileEntry is created. If I would want to save the fetched blob to the created FileEntry, within oReq.onload I could go on using a FileWriter, but only for small (I read up to 5 MB) files (since the Blob is handled in-memory). The blog post is more about how a blob can be fetched in general and not about it can be downloaded into the filesystem. If I would want to download bigger files (like a couple of 100 MB), moving away from cordova-plugin-filetransfer is not an option at the moment.

推荐答案

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

With this code you can download big images as they are written by blocks of 1MB instead of doing the whole write at once. Without the 1MB writting I wasn't able to write files bigger than 4MB, but with this I've tested with files up to 40MB without problems

 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', 'https://static.vix.com/es/sites/default/files/styles/large/public/imj/3/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);
        });
    }

这篇关于使用XHR2请求而不是cordova-file-transfer将二进制数据下载到应用程序沙箱中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆