cordova-plugin-file-transfer 1.6.0

cordova-plugin-file-transfer 1.6.0

测试已测试
语言语言 Obj-CObjective C
许可 Apache 2
发布上次发布2016 年 11 月

Holly SchinskyShazron Abdullah 维护。



 
依赖关系
Cordova>= 4.3.0
cordova-plugin-file>= 0
 

  • Adobe PhoneGap 团队

标题: 文件传输

描述: 上传和下载文件。

Android iOS Windows 8.1 Store Windows 8.1 Phone Windows 10 Store Travis CI
Build Status Build Status Build Status Build Status Build Status

cordova-plugin-file-transfer

此插件允许您上传和下载文件。

此插件定义了全局 FileTransferFileUploadOptions 构造函数。尽管在全局范围内,但它们在 deviceready 事件之前不可用。

document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
    console.log(FileTransfer);
}

要获取一些想法,请查看此页面底部的 示例 或直接访问 参考 内容。

Apache Cordova 问题跟踪器中报告此插件的错误

参考

安装

cordova plugin add cordova-plugin-file-transfer

支持的平台

  • Amazon Fire OS
  • Android
  • BlackBerry 10
  • 浏览器
  • Firefox OS**
  • iOS
  • Windows Phone 7 和 8*
  • Windows

*不支持 onprogressabort()

**不支持 onprogress

FileTransfer

FileTransfer 对象提供了一个使用 HTTP 多部分 POST 或 PUT 请求上传文件和下载文件的方法。

属性

  • onprogress:每次数据传输新块时都会调用 ProgressEvent(函数)

方法

  • upload:向服务器发送文件。

  • download:从服务器下载文件。

  • abort:中止正在进行的传输。

上传

参数:

  • fileURL:表示设备上文件的文件系统URL或数据URI。为了向后兼容,这也可以是设备上文件的完整路径。(见下文的向后兼容性说明

  • server:接收文件的服务器URL,由encodeURI()编码。

  • successCallback:传递一个FileUploadResult对象的回调。(函数)

  • errorCallback:如果发生错误检索FileUploadResult,则执行此回调。以FileTransferError对象调用。 (函数)

  • options:可选参数 (对象)。有效键

    • fileKey:表单元素的名称。默认为file。(DOMString)
    • fileName:在服务器上保存文件时使用的文件名。默认为image.jpg。(DOMString)
    • httpMethod:要使用的HTTP方法 - 键为PUTPOST。默认为POST。(DOMString)
    • mimeType:要上传的数据的MIME类型。默认为image/jpeg。(DOMString)
    • params:一组可选的关键/值对,用于传递HTTP请求。 (Object,键/值 - DOMString)
    • chunkedMode:是否以分块流模式上传数据。默认为true。(Boolean)
    • headers:一个表示标题名称/标题值的映射。使用数组指定多个值。在iOS、FireOS和Android中,如果存在名为Content-Type的标题,则不会使用多部分表单数据。(Object)
  • trustAllHosts:可选参数,默认值为false。如果设置为true,它接受所有安全证书。这在Android拒绝自签名安全证书时很有用。不推荐用于生产使用。支持Android和iOS。(布尔值)

示例

// !! Assumes variable fileURL contains a valid URL to a text file on the device,
//    for example, cdvfile://127.0.0.1/persistent/path/to/file.txt

var win = function (r) {
    console.log("Code = " + r.responseCode);
    console.log("Response = " + r.response);
    console.log("Sent = " + r.bytesSent);
}

var fail = function (error) {
    alert("An error has occurred: Code = " + error.code);
    console.log("upload error source " + error.source);
    console.log("upload error target " + error.target);
}

var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);
options.mimeType = "text/plain";

var params = {};
params.value1 = "test";
params.value2 = "param";

options.params = params;

var ft = new FileTransfer();
ft.upload(fileURL, encodeURI("http://some.server.com/upload.php"), win, fail, options);

示例(带上传标题和进度事件,仅支持Android和iOS)

function win(r) {
    console.log("Code = " + r.responseCode);
    console.log("Response = " + r.response);
    console.log("Sent = " + r.bytesSent);
}

function fail(error) {
    alert("An error has occurred: Code = " + error.code);
    console.log("upload error source " + error.source);
    console.log("upload error target " + error.target);
}

var uri = encodeURI("http://some.server.com/upload.php");

var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);
options.mimeType="text/plain";

var headers={'headerParam':'headerValue'};

options.headers = headers;

var ft = new FileTransfer();
ft.onprogress = function(progressEvent) {
    if (progressEvent.lengthComputable) {
        loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);
    } else {
        loadingStatus.increment();
    }
};
ft.upload(fileURL, uri, win, fail, options);

FileUploadResult

FileUploadResult对象传递给FileTransfer对象的upload()方法的成功回调。

属性

  • bytesSent:作为上传的一部分发送到服务器的字节数。(long)

  • responseCode:服务器返回的HTTP响应代码。(long)

  • response:服务器返回的HTTP响应。(DOMString)

  • headers:服务器返回的HTTP响应头。(Object)

    • 目前仅支持iOS。

iOS 特性

  • 不支持responseCodebytesSent

  • 不支持以chunkedMode=truemultipartMode=false上传空文件。

浏览器特性

  • withCredentials布尔值,告诉浏览器在XMLHttpRequest上设置withCredentials标志

Windows 特性

  • 由于Windows API设计,城乡选项参数带有空/空值会被排除在上传操作之外。

  • chunkedMode不受支持,所有上传都设置为非分块模式。

download

参数:

  • 来源:下载文件的文件服务器URL,由 encodeURI() 编码。

  • 目标:表示设备上文件的文件系统URL。为了兼容性,这也可能是设备上文件的完整路径。(见下面 兼容性说明)

  • 成功回调:传递一个 FileEntry 对象的回调。(函数)

  • 错误回调:在检索 FileEntry 时发生错误时执行的回调。使用一个 FileTransferError 对象调用。(函数)

  • trustAllHosts:可选参数,默认为 false。如果设置为 true,它接受所有安全证书。这对于Android拒绝自签名安全证书很有用。不建议用于生产使用。支持在Android和iOS上使用。(布尔值)

  • options:可选参数,目前仅支持头部(如Authorization(基本身份验证)等)。

示例

// !! Assumes variable fileURL contains a valid URL to a path on the device,
//    for example, cdvfile://127.0.0.1/persistent/path/to/downloads/

var fileTransfer = new FileTransfer();
var uri = encodeURI("http://some.server.com/download.php");

fileTransfer.download(
    uri,
    fileURL,
    function(entry) {
        console.log("download complete: " + entry.toURL());
    },
    function(error) {
        console.log("download error source " + error.source);
        console.log("download error target " + error.target);
        console.log("download error code" + error.code);
    },
    false,
    {
        headers: {
            "Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
        }
    }
);

WP8 的问题

  • 本地实现正在缓存下载请求。为了避免缓存,请将 if-Modified-Since 报头传递给下载方法。

浏览器的问题

  • withCredentials布尔值,告诉浏览器在XMLHttpRequest上设置withCredentials标志

中断

中断正在进行中的传输。当出现错误时,错误回调会将一个具有 FileTransferError.ABORT_ERR 错误代码的文件传输错误对象传递给 onerror 回调。

示例

// !! Assumes variable fileURL contains a valid URL to a text file on the device,
//    for example, cdvfile://127.0.0.1/persistent/path/to/file.txt

var win = function(r) {
    console.log("Should not be called.");
}

var fail = function(error) {
    // error.code == FileTransferError.ABORT_ERR
    alert("An error has occurred: Code = " + error.code);
    console.log("upload error source " + error.source);
    console.log("upload error target " + error.target);
}

var options = new FileUploadOptions();
options.fileKey="file";
options.fileName="myphoto.jpg";
options.mimeType="image/jpeg";

var ft = new FileTransfer();
ft.upload(fileURL, encodeURI("http://some.server.com/upload.php"), win, fail, options);
ft.abort();

文件传输错误

当发生错误时,将传递一个 FileTransferError 对象到错误回调。

属性

  • code:以下列出的预定义错误代码之一。(数字)

  • source:源的URL。(字符串)

  • target:目标的URL。(字符串)

  • http_status:HTTP状态代码。此属性仅在从HTTP连接收到响应代码时可用。(数字)

  • body 响应体。此属性仅在从HTTP连接收到响应时可用。(字符串)

  • exception:e.getMessage 或 e.toString(字符串)

常量

  • 1 = FileTransferError.FILE_NOT_FOUND_ERR
  • 2 = FileTransferError.INVALID_URL_ERR
  • 3 = FileTransferError.CONNECTION_ERR
  • 4 = FileTransferError.ABORT_ERR
  • 5 = FileTransferError.NOT_MODIFIED_ERR

Windows 的问题

兼容性说明

本插件的前几个版本只会接受绝对设备文件路径作为上传的来源,或者作为下载的目标。这些路径通常具有以下形式:

/var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)
/storage/emulated/0/path/to/file                                    (Android)

为了保持向后兼容性,这些路径仍然被接受,如果您的应用程序已经在持久存储中记录了类似这些路径,那么您仍然可以使用它们。

这些路径以前在File插件返回的FileEntry和DirectoryEntry对象的fullPath属性中被公开。然而,File插件的最新版本不再将这些路径公开给JavaScript。

如果您正在升级到新的File版本(1.0.0或更高版本),并且以前已将entry.fullPath用作download()upload()的参数,那么您需要修改您的代码以使用文件系统URL。

FileEntry.toURL()DirectoryEntry.toURL()返回以下格式的文件系统URL:

cdvfile://127.0.0.1/persistent/path/to/file

这可以在download()upload()方法中替代绝对文件路径。

示例:下载和上传文件

使用File-Transfer插件上传和下载文件。在这些示例中,我们展示了一些任务,如

将二进制文件下载到应用程序缓存

使用File插件配合File-Transfer插件为要下载的文件提供一个目标(目标必须是FileEntry对象)。在下载文件之前,通过使用resolveLocalFileSystemURL并在成功回调中调用fs.root来创建一个DirectoryEntry对象。使用DirectoryEntry的getFile方法创建目标文件。

window.requestFileSystem(window.TEMPORARY, 5 * 1024 * 1024, function (fs) {

    console.log('file system open: ' + fs.name);

    // Make sure you add the domain name to the Content-Security-Policy <meta> element.
    var url = 'https://cordova.net.cn/static/img/cordova_bot.png';
    // Parameters passed to getFile create a new file or return the file if it already exists.
    fs.root.getFile('downloaded-image.png', { create: true, exclusive: false }, function (fileEntry) {
        download(fileEntry, url, true);

    }, onErrorCreateFile);

}, onErrorLoadFs);

注意 对于持久性存储,通过将LocalFileSystem.PERSISTENT传递给requestFileSystem来请求。

当您有FileEntry对象时,使用FileTransfer对象的download方法下载文件。FileTransfer的download函数的第三个参数是成功回调,您可以使用它来调用应用的readBinaryFile函数。在这个代码示例中,entry变量是一个新的FileEntry对象,它接收下载操作的结果。

function download(fileEntry, uri, readBinaryData) {

    var fileTransfer = new FileTransfer();
    var fileURL = fileEntry.toURL();

    fileTransfer.download(
        uri,
        fileURL,
        function (entry) {
            console.log("Successful download...");
            console.log("download complete: " + entry.toURL());
            if (readBinaryData) {
              // Read the file...
              readBinaryFile(entry);
            }
            else {
              // Or just display it.
              displayImageByFileURL(entry);
            }
        },
        function (error) {
            console.log("download error source " + error.source);
            console.log("download error target " + error.target);
            console.log("upload error code" + error.code);
        },
        null, // or, pass false
        {
            //headers: {
            //    "Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
            //}
        }
    );
}

如果您只需要显示图像,请将FileEntry传递给其toURL()函数。

function displayImageByFileURL(fileEntry) {
    var elem = document.getElementById('imageElement');
    elem.src = fileEntry.toURL();
}

根据您的应用程序要求,您可能需要读取文件。为了支持二进制文件的操作,FileReader支持两个方法:readAsBinaryStringreadAsArrayBuffer。在这个示例中,使用readAsArrayBuffer并将FileEntry对象传递给该方法。一旦成功读取文件,使用读取的结果构造Blob对象。

function readBinaryFile(fileEntry) {
    fileEntry.file(function (file) {
        var reader = new FileReader();

        reader.onloadend = function() {

            console.log("Successful file read: " + this.result);
            // displayFileData(fileEntry.fullPath + ": " + this.result);

            var blob = new Blob([new Uint8Array(this.result)], { type: "image/png" });
            displayImage(blob);
        };

        reader.readAsArrayBuffer(file);

    }, onErrorReadFile);
}

成功读取文件后,可以使用createObjectURL创建一个DOM URL字符串,然后显示图像。

function displayImage(blob) {

    // Note: Use window.URL.revokeObjectURL when finished with image.
    var objURL = window.URL.createObjectURL(blob);

    // Displays image if result is a valid DOM string for an image.
    var elem = document.getElementById('imageElement');
    elem.src = objURL;
}

如您之前所看到的,您可以调用FileEntry.toURL()来仅显示下载的图像(跳过文件读取)。

上传文件

当您使用File-Transfer插件上传文件时,使用File插件提供要上传的文件(它们必须是FileEntry对象)。在您可以上传任何内容之前,使用DirectoryEntry的getFile方法为上传创建一个文件。在这个示例中,在应用程序缓存(fs.root)中创建文件,然后调用应用的writeFile函数以上传一些内容。

function onUploadFile() {
    window.requestFileSystem(window.TEMPORARY, 5 * 1024 * 1024, function (fs) {

        console.log('file system open: ' + fs.name);
        var fileName = "uploadSource.txt";
        var dirEntry = fs.root;
        dirEntry.getFile(fileName, { create: true, exclusive: false }, function (fileEntry) {

            // Write something to the file before uploading it.
            writeFile(fileEntry);

        }, onErrorCreateFile);

    }, onErrorLoadFs);
}

在这个示例中,创建一些简单的内容,然后调用应用的上传函数。

function writeFile(fileEntry, dataObj) {
    // Create a FileWriter object for our FileEntry (log.txt).
    fileEntry.createWriter(function (fileWriter) {

        fileWriter.onwriteend = function () {
            console.log("Successful file write...");
            upload(fileEntry);
        };

        fileWriter.onerror = function (e) {
            console.log("Failed file write: " + e.toString());
        };

        if (!dataObj) {
          dataObj = new Blob(['file data to upload'], { type: 'text/plain' });
        }

        fileWriter.write(dataObj);
    });
}

将FileEntry对象传递给上传函数。要执行实际的上传,请使用FileTransfer对象的upload函数。

function upload(fileEntry) {
    // !! Assumes variable fileURL contains a valid URL to a text file on the device,
    var fileURL = fileEntry.toURL();

    var success = function (r) {
        console.log("Successful upload...");
        console.log("Code = " + r.responseCode);
        // displayFileData(fileEntry.fullPath + " (content uploaded to server)");
    }

    var fail = function (error) {
        alert("An error has occurred: Code = " + error.code);
    }

    var options = new FileUploadOptions();
    options.fileKey = "file";
    options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);
    options.mimeType = "text/plain";

    var params = {};
    params.value1 = "test";
    params.value2 = "param";

    options.params = params;

    var ft = new FileTransfer();
    // SERVER must be a URL that can handle the request, like
    // http://some.server.com/upload.php
    ft.upload(fileURL, encodeURI(SERVER), success, fail, options);
};

下载上传的文件

要下载您刚刚上传的图像,您需要一个有效的URL来处理请求,例如 http://some.server.com/download.php。同样,FileTransfer.download 方法的成功处理器接收一个 FileEntry 对象。与之前的示例相比,这里的主要区别是我们调用 FileReader.readAsText 来读取下载操作的结果,因为我们上传了一个包含文本内容的文件。

function download(fileEntry, uri) {

    var fileTransfer = new FileTransfer();
    var fileURL = fileEntry.toURL();

    fileTransfer.download(
        uri,
        fileURL,
        function (entry) {
            console.log("Successful download...");
            console.log("download complete: " + entry.toURL());
            readFile(entry);
        },
        function (error) {
            console.log("download error source " + error.source);
            console.log("download error target " + error.target);
            console.log("upload error code" + error.code);
        },
        null, // or, pass false
        {
            //headers: {
            //    "Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
            //}
        }
    );
}

在 readFile 函数中,调用 FileReader 对象的 readAsText 方法。

function readFile(fileEntry) {
    fileEntry.file(function (file) {
        var reader = new FileReader();

        reader.onloadend = function () {

            console.log("Successful file read: " + this.result);
            // displayFileData(fileEntry.fullPath + ": " + this.result);

        };

        reader.readAsText(file);

    }, onErrorReadFile);
}