160

With HTML, how do I limit what kind of filetypes can be uploaded?

To easy the user experience, I want to limit file uploads to be only images (jpeg, gif, png).

<form method="post" action="..." enctype="multipart/form-data">
<label for="image">Photo</label>
<input name="image" type="file" />
</form>
JacobT
  • 3,021
  • 4
  • 22
  • 12
  • Obviously, to properply secure this - I would check on the backend/server side. But all I'm looking for is a way to simply the user experience so that when they click "browse" to find the image they want to upload, they are not having to see all of those word documents, etc that are not applicable to upload – JacobT Oct 13 '09 at 17:51
  • I don't know that you can set a file mask. I've never seen it done successfully. – Robert K Oct 13 '09 at 17:54

10 Answers10

277

HTML5 says <input type="file" accept="image/*">. Of course, never trust client-side validation: Always check again on the server-side...

Simon
  • 4,103
  • 7
  • 28
  • 53
Ms2ger
  • 15,596
  • 6
  • 36
  • 35
122

HTML5 File input has accept attribute and also multiple attribute. By using multiple attribute you can upload multiple images in an instance.

<input type="file" multiple accept="image/*">

You can also limit multiple mime types.

<input type="file" multiple accept="image/*,audio/*,video/*">

and another way of checking mime type using file object.

file object gives you name, size and type.

const files=e.target.files;
    
const mimeType=files[0].type; // You can get the mime type

You can also restrict the user for some file types to upload by the above code.

kongaraju
  • 9,344
  • 11
  • 55
  • 78
7

Edited

If things were as they SHOULD be, you could do this via the "Accept" attribute.

http://www.webmasterworld.com/forum21/6310.htm

However, browsers pretty much ignore this, so this is irrelavant. The short answer is, i don't think there is a way to do it in HTML. You'd have to check it server-side instead.

The following older post has some information that could help you with alternatives.

File input 'accept' attribute - is it useful?

Community
  • 1
  • 1
David
  • 72,686
  • 18
  • 132
  • 173
6

Here is the HTML for image upload. By default it will show image files only in the browsing window because we have put accept="image/*". But we can still change it from the dropdown and it will show all files. So the Javascript part validates whether or not the selected file is an actual image.

 <div class="col-sm-8 img-upload-section">
     <input name="image3" type="file" accept="image/*" id="menu_images"/>
     <img id="menu_image" class="preview_img" />
     <input type="submit" value="Submit" />
 </div> 

Here on the change event we first check the size of the image. And in the second if condition we check whether or not it is an image file.

this.files[0].type.indexOf("image") will be -1 if it is not an image file.

document.getElementById("menu_images").onchange = function () {
    var reader = new FileReader();
    if(this.files[0].size>528385){
        alert("Image Size should not be greater than 500Kb");
        $("#menu_image").attr("src","blank");
        $("#menu_image").hide();  
        $('#menu_images').wrap('<form>').closest('form').get(0).reset();
        $('#menu_images').unwrap();     
        return false;
    }
    if(this.files[0].type.indexOf("image")==-1){
        alert("Invalid Type");
        $("#menu_image").attr("src","blank");
        $("#menu_image").hide();  
        $('#menu_images').wrap('<form>').closest('form').get(0).reset();
        $('#menu_images').unwrap();         
        return false;
    }   
    reader.onload = function (e) {
        // get loaded data and render thumbnail.
        document.getElementById("menu_image").src = e.target.result;
        $("#menu_image").show(); 
    };

    // read the image file as a data URL.
    reader.readAsDataURL(this.files[0]);
};
TRiG
  • 10,148
  • 7
  • 57
  • 107
  • Add explanation please. – Paul Swetz Jun 28 '16 at 14:28
  • Please note that the above requires jquery, but does not say so. Easy enough to figure out, but helpful to state. I created [a fiddle for this](https://jsfiddle.net/dland/n3uL3njh/). It does some other things (as required for a project), but the concept is very much the same. – Dave Land Jun 17 '17 at 00:35
4

This is what I have been using successfully:

...
<div class="custom-file">
    <input type="file" class="custom-file-input image-gallery" id="image-gallery" name="image-gallery[]" multiple accept="image/*">
   <label class="custom-file-label" for="image-gallery">Upload Image(s)</label>
</div>
...

It is always a good idea to check for the actual file type on the server-side as well.

hackernewbie
  • 1,606
  • 20
  • 13
2
<script>

    function chng()
    {
        var typ=document.getElementById("fiile").value;
        var res = typ.match(".jp");

        if(res)
        {
            alert("sucess");
        }
        else
        {
            alert("Sorry only jpeg images are accepted");
            document.getElementById("fiile").value="; //clear the uploaded file
        }
    }

</script>

Now in the html part

<input type="file" onchange="chng()">

this code will check if the uploaded file is a jpg file or not and restricts the upload of other types

Ninita
  • 1,209
  • 2
  • 19
  • 45
  • This check is defeated by a simple renaming of the file extension. You should at least check the data URI type if you're going to do something like this. – Lucas Leblanc Oct 23 '18 at 15:37
1

You can only do this securely on the server-side. Using the "accept" attribute is good, but must also be validated on the server side lest users be able to cURL to your script without that limitation.

I suggest that you: discard any non-image file, warn the user, and redisplay the form.

Robert K
  • 30,064
  • 12
  • 61
  • 79
1

Because <input type="file" id="fileId" accept="image/*"> can't guarantee that someone will choose an image, you need some validation like this:

if(!(document.getElementById("fileId").files[0].type.match(/image.*/))){
                alert('You can\'t upload this type of file.');
                return;
}
Aleksandra
  • 21
  • 4
0

Ultimately, the filter that is displayed in the Browse window is set by the browser. You can specify all of the filters you want in the Accept attribute, but you have no guarantee that your user's browser will adhere to it.

Your best bet is to do some kind of filtering in the back end on the server.

John Lechowicz
  • 2,573
  • 3
  • 21
  • 34
0

Checkout a project called Uploadify. http://www.uploadify.com/

It's a Flash + jQuery based file uploader. This uses Flash's file selection dialog, which gives you the ability to filter file types, select multiple files at the same time, etc.

AndrewR
  • 6,668
  • 1
  • 24
  • 38
  • 1
    Guys, I don't see why it's the worst solution ever. Though it's true Flash is going to disappear, it's still being used by old browsers - very old, ok, but still is being used - and this solution has both type of technologies: jQuery + HTML5 & Flash fallback. It's as good as VideoJS, which has a Flash fallback in case the browser cannot play the video... I haven't tested the solution, it can be not the best, but the downvotes are not fair. – Unapedra Jun 26 '14 at 10:43
  • 1
    +1 Silly to vote down. Flash is going away but has good fallback. What do you think Google uses for gmail for socket fallback? Silly. – King Friday Oct 20 '14 at 01:14
  • 8
    This answer is 4 years old. At the time, HTML5 support for multiple file selection or filtering the select file window by the accepted types was not well supported in any of the major browsers. This was a solution that would have worked for many at the time, but I'd move toward a pure HTML5 solution now. – AndrewR Apr 16 '15 at 15:58
  • @AndrewR please update the answer as it is updated now. – Ulrich Dohou Oct 11 '19 at 23:02