Reputation: 3015
The use of DATA_URL is not recommended due to performance issues but I need the byte array to upload directly to my server
I am wondering if it is even possible to use DATA_URL with ALLMEDIA seeing as DATA_URL will just return an array of bytes without an idea of what the file name or file extension is. If we're always uploading images this isn't much of an issue but I'd like the user to upload documents and pdf as well
Is there any way to extract this information?
Upvotes: 0
Views: 474
Reputation: 314
DATA_URL will never return file name or extension..
Use FILE_URI instead if you want to have the complete path with the file name. If you do no mention the destinationType at all, it will return FILE_URI by default.
Which then you can convert into cdv path from native using the following
resolveLocalFileSystemURL(imageFinal, function(entry) {
console.log("here is the file path: " + entry.toInternalURL());
});
Upvotes: 0
Reputation: 2417
Filenames are arbitrary to its file contents. You can get a filename dynamically using the cordova-plugin-file APIs, but it's up to you to tell the server if a specific filename should be used and it's up to the server to actually use this information. I'll provide two different ways below.
DATA_URL
also doesn't return a byte array, it returns a base64 encoded string. If you want a byte array, you can use the file plugin to read the file as ArrayBuffer
via readAsArrayBuffer
. XMLHttpRequest
can accept ArrayBuffer
or Blob
objects to send raw binary data, which is far more memory efficient than handling base64 strings. This will be shown in both examples below.
You can get the filename using the cordova-plugin-file APIs and send that to the server via a HTTP header. Example follows
function readBinaryFile(fileEntry) {
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function() {
console.log("Successful file write: " + this.result);
displayFileData(fileEntry.fullPath + ": " + this.result);
var blob = new Blob([new Uint8Array(this.result)], { type: "image/png" });
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://example.com/upload');
xhr.setRequestHeader('X-FILENAME', file.name);
xhr.send(blob);
};
reader.readAsArrayBuffer(file);
}, onErrorReadFile);
}
Alternatively, if you can't use HTTP headers for whatever reason, then you can construct a FormData
object and append blobs and strings alike as a multipart form request. Example follows:
function readBinaryFile(fileEntry) {
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function() {
console.log("Successful file write: " + this.result);
displayFileData(fileEntry.fullPath + ": " + this.result);
var blob = new Blob([new Uint8Array(this.result)], { type: "image/png" });
var form = new FormData();
form.append('filename', file.name);
form.append('file', blob);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://example.com/upload');
xhr.send(form);
};
reader.readAsArrayBuffer(file);
}, onErrorReadFile);
}
Using the FormData
method, you'll likely want to use a FormData
library that can read/parse multipart forms.
Disclaimer: Examples are not tested, but mostly came from cordova-plugin-file docs
Lastly, don't forget to sanitise the filename. You don't want the user prodding your server by uploading a file named ../someImportantDataFile
and overwriting things ;)
Upvotes: 1