DGK
DGK

Reputation: 3015

Cordova camera plugin DATA_URL does not return filename or extension

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

Answers (2)

Riya Singh
Riya Singh

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

Norman Breau
Norman Breau

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.

HTTP Header Method

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);
}

FormData Method

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

Related Questions