2016-07-31 162 views
2

我使用FormData与AJAX(对于进度条,但我省略了简单的代码)上传文件:为什么FileEntry的FormData.append文件不能正确上传?

<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科尔多瓦手机应用程序相同的代码,但我添加了一个“拍照”按钮,它采用navigator.camera.getPictureFileEntry.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对象,因为它不会自动添加文件名属性,也不会自动添加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 
+0

也许FileEntry.file没有用正确的格式的工作?您也可以尝试将结果添加到Blob中,并以此方式创建File对象。新的Blob([data],{type:“image/png”}); – Bram

+0

@Bram嗨布拉姆,我不知道你的意思,因为文件从Blob继承。 – Kevin

回答

1

使用科尔多瓦文件传输plugin.There你需要给文件的URL来upload.You可以在这里找到参考link

+0

这工作。这有点烦人,因为我没有jQuery.ajax的所有便利(例如,不得不调用'jQuery.parseJSON(result.response)')。 – Kevin

+0

ok Cheers @kelvin – Homen

0

,我认为它是内容类型不设置为文件的multipart/form-data的,通过一个虚拟形式的加密类型是多/表单数据,然后添加你想要添加到它的领域,即

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

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

我认为应该至少有帮助。

+0

正确的观点,但是为了简化我的代码片段,我将其从代码片段中删除了,但它存在于代码中。我现在很确定(写一个问题有助于澄清!)问题是FileEntry.file返回一个不能从File继承的“File”对象。我认为这是嵌入式WebView中的一个错误。我目前正在调查如何从它得到一个适当的文件对象... – Kevin

+0

owk酷,仍然会调查它,如果你最终得到请你不要评论或分享 –

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); 
    }); 
}); 
相关问题