Cordova 5.1.1中的FormData与相机操作无法正常工作

时间:2015-07-15 15:04:26

标签: javascript android file cordova form-data

我正在尝试使用Cordova相机插件拍照。拍摄照片后,我创建一个新的FormData对象来附加图像。我将相机创建的Base64图像转换为Blob,然后将其附加到新的FormData对象。不幸的是,Blob永远不会附加。

我有 Nexus 5 正在运行 Android 5.1.1 。我使用 Cordova 5.1.1 CordovaLib 4.0.2 构建了一个应用程序。我安装了以下插件:

科尔多瓦-插件装置 科尔多瓦 - 插件,inappbrowser 科尔多瓦 - 插件相机 科尔多瓦 - 插件文件 科尔多瓦 - 插件 - 文件传输 科尔多瓦-插件白名单

同样的问题出现在Cordova 4.3.1& CordovaLib android 3.7.2。

以下是我用来激活设备相机的代码片段。

navigator.camera.getPicture(
 onSuccess,
 onFailure, 
 {
   quality: 50,
   destinationType: Camera.DestinationType.DATA_URL,
   cameraDirection: Camera.Direction.FRONT
 }
);

以下是成功与失败的功能。

function onSuccess(URI) {
  var the_file = new Blob([window.atob(URI)],  {type: 'image/jpeg', encoding: 'utf-8'});
  try {
    var fd = new FormData();
    fd.append('Filedata', the_file, "selfie.jpg");
  } catch (e) {
    throw e;
  }
  console.log(the_file.size);
  console.log(the_file.type);
  console.log(JSON.stringify(fd));
}
function onFailure(e) {
  console.log(e);
}

当我运行此代码时,我会监控Android Studio中的控制台输出。我可以看到the_file.size和the_file.type是正确的。但是,FormData的“JSON.stringify”显示一个空对象“{}”。

我知道我应该在Cordova中使用FILE_URL而不是DATA_URL来节省内存,但我现在正处于我需要调试此FormData问题的位置。一旦我让这个例子工作,那么在我将我的应用程序投入生产之前,我将重构我的代码以使用FILE_URL。我想重点关注为什么FormData.append函数不适用于我正在创建的Blob。任何见解将不胜感激!

谢谢, 亚伦

1 个答案:

答案 0 :(得分:1)

经过更多测试后,我发现FormData在Cordova 5.1.1中无法正常工作。我在Cordova 4.2.3和5.0中也发现它与它不一致。

在cordova中使用Camera上传文件的解决方案是使用FileTransfer对象和文件系统。

下面是一个经过修改的onSuccess函数,演示了如何从Camera中提取图像并将其上传到服务器。永远不需要FormData。

onSuccess: function (URI) {
    window.resolveLocalFileSystemURL(URI, function (fileEntry) {
            console.log("Got URI");
            console.log(JSON.stringify(fileEntry));
            fileEntry.file(function (fileInput) {
                console.log(fileInput.localURL);
                var ft = new FileTransfer();

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

                ft.upload(
                    fileInput.localURL,
                    encodeURI("http://www.posttestserver.com/post.php?dir=CordovaExample"),
                    function (r) {
                        console.log("Code = " + r.responseCode);
                        console.log("Response = " + r.response);
                        console.log("Sent = " + r.bytesSent);
                    },
                    function (e) {
                        alert("An error has occurred: Code = " + error.code);
                        console.log("upload error source " + error.source);
                        console.log("upload error target " + error.target);
                    },
                    options,
                    true
                );
            }
    }
}

需要指出的重要一点是,我们不使用从Camera发送到onSuccess函数的原始URL。我们从window.resolveLocalFileSystemURL函数返回的FileEntry对象中提取实际的文件系统URL。

不幸的是,FormData的问题没有记录在我能找到的任何地方。我在页面底部的https://github.com/apache/cordova-plugin-file-transfer的Cordova FileTransfer插件的向后兼容性说明中偶然发现了URL与localURL的关系。

  

FileEntry.toURL()和DirectoryEntry.toURL()返回cdvfile:// localhost / persistent / path /到/ file形式的文件系统URL,可用于代替下载()中的绝对文件路径和upload()方法。

我也无法使用FileReader打开已保存的照片并将其附加到FormData。我相信新Cordova中的FormData API存在问题。我也知道过去版本中的API不一致。我的建议是避免使用FormData并使用上面概述的技术从Cordova的相机或文件系统中获取图像。