44

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!

0

10 Answers 10

88

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.
}
Sign up to request clarification or add additional context in comments.

8 Comments

God, why I haven't thought about this? So simple, yet works perefectly, thank you!
You shouldn't use capital letters to start a variable's name in Javascript.
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 ?
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 for a valid solution
In the documentation it is at bold this: "Developers are advised not to rely on this property as a sole validation scheme." developer.mozilla.org/docs/Web/API/File/type#Example.
|
44

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

1 Comment

changing the extension actually affects the result
12

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; 

1 Comment

This should be the accepted answer. Other answers user file.type, that only have the information of the file extension. For more information check developer.mozilla.org/docs/Web/API/File/type#Example
7

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) {
  ...
}

Comments

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' />

2 Comments

Somehow I managed to miss this .type thingy, no sophisticated methods are needed, this works great, thank you (:
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.
3

A lot of convoluted answers here. Simply check whether the file has an image mime-type (which would be of the format image/...

const isImage = file => file.type.startsWith("image/")

Comments

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.

Comments

1
$('#direct_upload').change(function() {

      if (this.files[0].type.includes('image')) {
        document.getElementById('attach_file').src = window.URL.createObjectURL(this.files[0])
      } else {
        console.log('it is a doc');
      }
}

Comments

0

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}

Comments

0

Using jQuery version 3.3.1:

<!DOCTYPE html>
<html>

<head>
  <title>Page Title</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>

<body>
  <label class="custom-file-label" for="customFile">Select Image</label>
  <br>
  <input type="file" class="custom-file-input" id="customFile">
</body>

<script>
  $(document).ready(function() {
    $(document).on("change", ".custom-file-input", function() {
      var myImg = this.files[0];
      var myImgType = myImg["type"];
      var validImgTypes = ["image/gif", "image/jpeg", "image/png"];

      if ($.inArray(myImgType, validImgTypes) < 0) {
        alert("Not an image")
      } else {
        alert("Is an image")
      }

    });
  });
</script>

</html>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.