I'm using FormData to upload files with AJAX (for progress bars, although I've omitted that code for simplicity):
<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...
}
This works fine. Next, I have the same code in an Apache Cordova phone application, but I add a "Take Picture" button as an option underneath each file input which uses navigator.camera.getPicture and FileEntry.file to get the File object and call the same uploadFile function:
$(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...
This does not work - the server just gets "[object Object]" instead of the file.
Connecting Chrome Developer Tools to the Android app, I see this part of the request payload in the failing case:
------WebKitFormBoundaryThmH13yROUHXJ4jB
Content-Disposition: form-data; name="identity_file[file]"
[object Object]
In the working case:
------WebKitFormBoundaryztHB86BlcKBZ9dPX
Content-Disposition: form-data; name="identity_file[file]"; filename="0DuheTR.jpg"
Content-Type: image/jpeg
I guess in the working case it doesn't actually show the file payload, but I can confirm it works.
It seems that in the failing case, it doesn't see the File object correctly, because it doesn't automatically add the filename attribute, nor the Content-Type, and also seems to just do a naive toString for the body. The app is built with Cordova 6.2.0 and running on Android 6.0.1.
I ran console.dir on the File object in both cases and they look about the same, although the proto in the failing case is Object instead of File - why?
Working:
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
Failing:
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