当前位置: 首页 > 面试题库 >

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

桑鸿志
2023-03-14
问题内容

科尔多瓦正在“废除” 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 <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打算放弃文件传输插件,而倾向于通过Ajax直接获取Blob。

我看到这个权利了吗:
fs.root.getFile创建一个文件。下载成功处理程序(oReq.onload)不会尝试将获取的Blob写入创建的文件。没有明确的理由创建fileEntry。如果我想将获取的Blob保存到创建的FileEntry中,则oReq.onload
可以继续使用FileWriter,但仅适用于小型文件(我最多读取5
MB)(因为Blob在内存中处理)。该博客文章更多地是关于如何一般地获取blob,而不是有关如何将其下载到文件系统中。如果我要下载较大的文件(例如100
MB的文件),则目前不选择退出cordova-plugin-filetransfer。


问题答案:

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

 window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory, 
    function (dirEntry) {
        console.log('file system open: ' + dirEntry.name);
        createFile(dirEntry, "downloadedImage.jpg");
    }, onFSError);
    function onFSError(error) {
        alert(JSON.stringify(error));
    }
    function createFile(dirEntry, fileName) {
        // 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);
        });
    }


 类似资料:
  • 问题内容: 我正在开发一个RESTful Web应用程序(Django + Piston)。POST请求将使用Json编码的数据发送到Web应用程序。这对于我所有的纯文本数据库表都很好,但是我还有一个存储文本和二进制文件的表。将文本和二进制数据发布到RESTful应用程序的最佳方法是什么? 问题答案: 您可以对它进行Base64编码并以字符串形式将其发送到JSON消息中,也可以将二进制文件作为单独

  • 我试图下载一个二进制文件,并将其原始名称保存在磁盘上(linux)。 有什么想法吗?

  • 我对Cordova完全陌生,但现在我已经用NPM安装了Cordova,安装了Android SDK,并设置了一个AVD,它似乎工作得很好,直到我想要模拟我的项目。由于某种原因,实际应用程序没有加载到模拟器中。 执行以下操作: 然后启动Android emulator,但应用程序不存在。是否有人建议修复此问题,以便我能够在模拟器中进行实际测试? 提前谢谢你。

  • 问题内容: 我在项目和构建系统(例如Travis CI)中使用Go模块,正在下载一个命令行实用程序(用Go编写)以协助构建过程,例如: 但是,这导致文件被添加到我的文件中。这污染了构建环境,使其变得“脏”(因为git中跟踪的某些文件发生了更改,在本例中为go.mod和go.sum),我用它来描述构建,其显示为“脏”。 有没有一种方法可以直接下载二进制文件而不将其添加到go.mod / go.sum

  • 默认情况下,Android Pie会要求应用程序使用HTTPS连接而不是HTTP。因此无法在HTTP中命中restful API

  • 问题内容: 我尝试使用以下代码下载pdf文件。它存储在应用程序数据中。但是我需要在iPhone的 “文件” 文件夹中显示下载的pdf 。 可能吗?? 问题答案: 这是下载任何文件并保存到“照片”(如果是图像文件)或“文件”(如果是pdf)的方法