30

Newbie here. The problem is that I currently have written a method which checks uploaded file size and extension in order to validate it. However, checking extensions is not a solution as that kind of validation may cause a lot of problems. What I want to do is to check the actual file type and validate it without using extension method. I have tried to use jQuery file validator but to no avail... This is a snippet from my current code:

<input type='file' id='imageLoader' name='imageLoader' accept="image/*" data-type='image' />

Script:

App.Dispatcher.on("uploadpic", function() {         
        $(":file").change(function() {
            if (this.files && this.files[0] && this.files[0].name.match(/\.(jpg|jpeg|png|gif)$/) ) {
                if(this.files[0].size>1048576) {
                    alert('File size is larger than 1MB!');
                }
                else {
                    var reader = new FileReader();
                    reader.onload = imageIsLoaded;
                    reader.readAsDataURL(this.files[0]);
                }
            } else alert('This is not an image file!');
        });
        function imageIsLoaded(e) {
            result = e.target.result;
            $('#image').attr('src', result);
        };
    });

It is called once the upload input changes and after validation it uploads and displays the image. For now, I only care about validation and any help or ideas would be greatly appreciated!

Acallar
  • 323
  • 1
  • 3
  • 5

7 Answers7

71

Try something like this:

JavaScript

const file = this.files[0];
const  fileType = file['type'];
const validImageTypes = ['image/gif', 'image/jpeg', 'image/png'];
if (!validImageTypes.includes(fileType)) {
    // invalid file type code goes here.
}

jQuery

var file = this.files[0];
var fileType = file["type"];
var validImageTypes = ["image/gif", "image/jpeg", "image/png"];
if ($.inArray(fileType, validImageTypes) < 0) {
     // invalid file type code goes here.
}
Raja Rama Mohan Thavalam
  • 5,212
  • 2
  • 25
  • 27
Hoyen
  • 2,246
  • 1
  • 10
  • 12
  • 1
    God, why I haven't thought about this? So simple, yet works perefectly, thank you! – Acallar Apr 23 '15 at 07:28
  • 9
    You shouldn't use capital letters to start a variable's name in Javascript. – Yonn Trimoreau Mar 08 '16 at 15:46
  • When I tried the same for docx extension files then file type is empty. Can you tell why it is and how I can check this ? – Varinder Nov 28 '16 at 14:03
  • @Varinder may be you can post a question on what you tried? This should be able to work with Microsoft Word documents as well. – Hoyen Nov 28 '16 at 14:26
  • Don't forget image/svg+xml – rboarman Nov 27 '18 at 21:51
  • 3
    This answer isn't right. If you change the extension of a file to, for example, .png or .jpg, you will always get a valid image file, even if your file is a pdf, txt or something not related with an image. Check @sujit answer or [this](https://stackoverflow.com/questions/32222786/file-upload-check-if-valid-image) for a valid solution – bruno.almeida Nov 28 '18 at 15:09
  • In the documentation it is at bold this: "Developers are advised not to rely on this property as a sole validation scheme." https://developer.mozilla.org/docs/Web/API/File/type#Example. – bruno.almeida Nov 28 '18 at 15:18
34

You don't need jquery here.

var mimeType=this.files[0]['type'];//mimeType=image/jpeg or application/pdf etc...


//ie image/jpeg will be ['image','jpeg'] and we keep the first value
    if(mimeType.split('/')[0] === 'image'){
       console.log('the file is image');
    }

You can also create a function to check when a file is image.

function isImage(file){
   return file['type'].split('/')[0]=='image');//returns true or false
}

 isImage(this.file[0]);

Update (es6)

using es6 includes method, makes it even more simple.

const isImage = (file) => file['type'].includes('image');
Mike Antoniadis
  • 567
  • 6
  • 12
5

Pls refer a related query here. The answer here suggests to load the image in an Image object and check for it's width and height properties to be non zero. I think the technique can be used to solve your problem too.

I also worked out a fiddle for you to refer. Pertinent code below:

var img = new Image();
img.addEventListener("load",function(){
  alert('success');
});
img.addEventListener("error",function(){
      alert('error');
});
  img.src = picFile.result; 
Community
  • 1
  • 1
sujit
  • 2,028
  • 1
  • 11
  • 22
  • This should be the accepted answer. Other answers user `file.type`, that only have the information of the file extension. For more information check https://developer.mozilla.org/docs/Web/API/File/type#Example – bruno.almeida Nov 28 '18 at 15:17
5

Here is a quick tip if you just want to know if the file is an image:

var file = this.files[0];
var fileType = file["type"];

if (fileType.search('image') >= 0) {
  ...
}
rom5jp
  • 616
  • 10
  • 13
4

What I want to do is to check the actual file type

Try accessing files[0].type property . See Using files from web applications

$(":file").on("change", function(e) {

  console.log(this.files[0].type);
  
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type='file' id='imageLoader' name='imageLoader' accept="image/*" data-type='image' />
guest271314
  • 1
  • 10
  • 82
  • 156
  • Somehow I managed to miss this .type thingy, no sophisticated methods are needed, this works great, thank you (: – Acallar Apr 23 '15 at 07:29
  • 1
    Just curious. As per your original question "However, checking extensions is not a solution as that kind of validation may cause a lot of problems. What I want to do is to check the actual file type": - Want to check whether the type attribute really returns anything other than checking the extension internally. Since, while I was attempting to answer the OP, i found that when i renamed a text file to a.png and uploaded it, the type attribute check for image was a success even though the actual file wasn't one. – sujit Apr 24 '15 at 04:39
2

If anyone comes here who is using jQuery Validator, a simple method would be:

jQuery.validator.addMethod(
    "onlyimages",
    function (value, element) {
        if (this.optional(element) || !element.files || !element.files[0]) {
            return true;
        } else {
            var fileType = element.files[0].type;
            var isImage = /^(image)\//i.test(fileType);
            return isImage;
        }
    },
    'Sorry, we can only accept image files.'
);

which is then added to the .validate() function.

Neil Thompson
  • 6,116
  • 2
  • 25
  • 50
1

You could try to convert file type in string and after that slice this string like that:

if(String(file.type).slice(0, 6) === 'image/') {....some code}
Oleg Sewruk
  • 873
  • 7
  • 11