Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Html File Input on Chrome for Android missing extension and mime type

In html/js, when you select a file on Chrome (43) for Android (5.1.1), the resulting files name is missing the extension and the file type is an empty string. Wondering if there is way to get the missing information? And if not, is there a reasonable way to do clientside side validation on file types?

Please see the example fiddle below and note that I get extension and mime type on windows desktop browsers and ios safari.

http://jsfiddle.net/Lfg3xhy4/

$(function(){
    $("#fileInput").on("change", function(e){
        $("#name").html(e.target.files[0].name);
        $("#type").html(e.target.files[0].type);
    });
});

Update I noticed when using the android Documents browser, the Audio tab (which I was using to select files) does not seem to supply file extension and mime type. If I navigate to files using any other tab, everything seems ok.

like image 473
Kenneth Ito Avatar asked Jun 07 '15 01:06

Kenneth Ito


1 Answers

Via the android Documents file browser, some of the tabs do not provide file extension and type. The Audio tab (which displays audio metadata) and some of the connected storage accounts for example.

As such, another way to do file type validation is to use "file signatures" http://www.filesignatures.net/index.php?page=all

Essentially you take a look at a portion of the binary file. Simplified example below.

var audioFile;  //Set from elsewhere
if (FileReader) {
    var reader = new FileReader();
    reader.addEventListener("load", function(e) {
        var mp3FileSignature = [255, 251, 48];
        var id3FileSignature = [73, 68, 51];
        //There are actually quite a few more scenarios to handle for mp3's in particular
        //Most file types are simpler

        var arrayBuffer = e.target.result;

        if (arrayBuffer && arrayBuffer.byteLength >= 3) {
            var slice = arrayBuffer.slice(0, 3);
            var view = new Uint8Array(slice);
            if ((mp3FileSignature[0] != view[0] || mp3FileSignature[1] != view[1] || mp3FileSignature[2] != view[2])  
                && (id3FileSignature[0] != view[0] || id3FileSignature[1] != view[1] || id3FileSignature[2] != view[2])) {

                //Not an mp3
            }
        }

    })
    reader.readAsArrayBuffer(audioFile);
}
like image 142
Kenneth Ito Avatar answered Sep 20 '22 08:09

Kenneth Ito