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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.