为什么FileEntry中的FormData.append文件没有正确上传?

时间:2016-07-31 20:11:15

标签: javascript android cordova

我正在使用FormData上传带有AJAX的文件(对于进度条,虽然我为了简单起见省略了该代码):

<form method="post" enctype="multipart/form-data">
  <input type="file" name="file" />
</form>
$(document).ready(function() {
  $(document).on("change", ":file", function() {
    var i;
    for (i = 0; i < this.files.length; i++) {
      var file = this.files[i];
      uploadFile(this.name, file);
    }
  }
}

function uploadFile(inputName, file) {
  var formData = new FormData();
  formData.append(inputName, file);
  $.ajax({
    type: "POST",
    url: "/api/newfile",
    data: formData,
    timeout: 0,
    cache: false,
    contentType: false,
    processData: false
  }) // some code omitted...
}

这很好用。接下来,我在Apache Cordova手机应用程序中有相同的代码,但我在每个文件输入下面添加了一个“拍照”按钮,使用navigator.camera.getPictureFileEntry.file来获取File对象并调用相同的uploadFile函数:

$(document).ready(function() {
  $("input:file").each(function(index) {
    $("<button class='take_picture_button ui-btn'>Take Picture</button>").insertAfter($(this));
  });

  $(document).on("click", ".take_picture_button", function(e) {
    $inputFileElement = $(this).prev("input:file").first();
    navigator.camera.getPicture(function(fileURI) {
      window.resolveLocalFileSystemURL(fileURI, function(fileEntry) {
        fileEntry.file(function(file) {
          uploadFile($inputFileElement.attr("name"), file);
        });
      });
    });
  });
}); // some code omitted...

这不起作用 - 服务器只获取“[object Object]”而不是文件。

将Chrome开发者工具连接到Android应用,我在失败的情况下看到请求有效负载的这一部分:

------WebKitFormBoundaryThmH13yROUHXJ4jB
Content-Disposition: form-data; name="identity_file[file]"

[object Object]

在工作案例中:

------WebKitFormBoundaryztHB86BlcKBZ9dPX
Content-Disposition: form-data; name="identity_file[file]"; filename="0DuheTR.jpg"
Content-Type: image/jpeg

我想在工作情况下它实际上并没有显示文件有效负载,但我可以确认它有效。

似乎在失败的情况下,它没有正确地看到File对象,因为它不会自动添加filename属性,也不会自动添加Content-Type,而且似乎只为身体做了一个天真的toString 。该应用程序使用Cordova 6.2.0构建,并在Android 6.0.1上运行。

我在两个案例中都在File对象上运行了console.dir,它们看起来大致相同,虽然失败案例中的 proto 是Object而不是File - 为什么?

工作:

File
  lastModified: 1458490019474
  lastModifiedDate: Sun Mar 20 2016 09:06:59 GMT-0700 (PDT)
  name: "0DuheTR.jpg"
  size: 152054
  type: "image/jpeg"
  webkitRelativePath: ""
  __proto__: File

出现故障:

File
  end: 785009
  lastModified: 1469992497000
  lastModifiedDate: 1469992497000
  localURL: "cdvfile://localhost/cache-external/1469992495873.jpg"
  name: "1469992495873.jpg"
  size: 785009
  start: 0
  type: "image/jpeg"
  __proto__: Object

3 个答案:

答案 0 :(得分:1)

使用cordova文件传输插件。您需要提供要上传的文件URL。您可以在此处找到引用link

答案 1 :(得分:0)

我认为内容类型没有设置为文件multipart / form-data,传递一个伪形式,即enctype是multipart / form-data,然后追加你要添加到其中的字段,即

<form method="post" enctype="multipart/form-data"></form>

var form=new FormData($("form"));

我认为应该至少提供帮助。

答案 2 :(得分:0)

问题已经回答here。您需要使用FileReader将文件对象进一步转换为Blob。

我只想引用它的要点:

var formData = new FormData();
window.resolveLocalFileSystemURL(fileURI, function(fileEntry) {
    fileEntry.file(function(file) {
        var reader = new FileReader();
        reader.onloadend = function(e) {
            var imgBlob = new Blob([this.result], {type:"image/jpeg"});
            formData.append('image', imgBlob);
            //post formData here
        };
        reader.readAsArrayBuffer(file);
    });
});