I'd like to restrict the type of file that can be chosen from the native OS file chooser when the user clicks the Browse button in the <input type="file">
element in HTML. I have a feeling it's impossible, but I'd like to know if there is a solution. I'd like to keep solely to HTML and JavaScript; no Flash please.

- 18,928
- 4
- 42
- 62

- 99,427
- 50
- 170
- 208
-
3Its easily possible with PHP, but I don't know if you can use that so I won't post the code. – Latox Dec 01 '10 at 20:48
-
4I can, but I have a solution working with JavaScript - it removes the annoyance of uploading a file *then* getting the "Wrong file!" error. – Bojangles Dec 01 '10 at 20:49
-
Also see more recent question: https://stackoverflow.com/questions/181214/file-input-accept-attribute-is-it-useful – Christophe Roussy Sep 25 '18 at 12:27
-
2One thing to note is that while it is not great for validation, accept will limit the visible files to the accepted ones while the user is browsing them (at least in some browsers ...). So this is more a UI ergonomy feature than a validation one. – Christophe Roussy Sep 25 '18 at 12:31
12 Answers
Strictly speaking, the answer is no. A developer cannot prevent a user from uploading files of any type or extension using front-end validation (HTML/JavaScript).
But still, the accept attribute of <input type = "file">
can help to provide a filter in the file select dialog box provided by the user's browser/OS. For example,
<!-- (IE 10+, Edge (EdgeHTML), Edge (Chromium), Chrome, Firefox 42+) -->
<input type="file" accept=".xls,.xlsx" />
should provide a way to filter out files other than .xls or .xlsx. Although the MDN page for input
element always said that it supports this, to my surprise, this didn't work for me in Firefox until version 42. This works in IE 10+, Edge, and Chrome.
So, for supporting Firefox older than 42 along with IE 10+, Edge, Chrome, and Opera, I guess it's better to use comma-separated list of MIME-types:
<!-- (IE 10+, Edge (EdgeHTML), Edge (Chromium), Chrome, Firefox) -->
<input type="file"
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" />
[Edge (EdgeHTML) behavior: The file type filter dropdown shows the file types mentioned here, but is not the default in the dropdown. The default filter is All files (*)
.]
You can also use asterisks in MIME-types. For example:
<input type="file" accept="image/*" /> <!-- all image types -->
<input type="file" accept="audio/*" /> <!-- all audio types -->
<input type="file" accept="video/*" /> <!-- all video types -->
W3C recommends authors to specify both MIME-types and their corresponding extensions in the accept
attribute. So, the best approach is:
<!-- Right approach: Use both file extensions and their corresponding MIME-types. -->
<!-- (IE 10+, Edge (EdgeHTML), Edge (Chromium), Chrome, Firefox) -->
<input type="file"
accept=".xls,.xlsx, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" />
JSFiddle of the same: here.
Reference: List of MIME-types
IMPORTANT: Using the accept
attribute only provides a way of filtering in the files of types that are of interest. Browsers still allow users to choose files of any type. Additional (client-side) checks should be done (using JavaScript, one way would be this), and definitely file types MUST be verified on the server, using a combination of MIME-type using both the file extension and its binary signature (ASP.NET, PHP, Ruby, Java). You might also want to refer to these tables for file types and their magic numbers, to perform a more robust server-side verification.
Here are three good reads on file-uploads and security.
EDIT: Maybe file type verification using its binary signature can also be done on client side using JavaScript (rather than just by looking at the extension) using HTML5 File API, but still, the file must be verified on the server, because a malicious user will still be able to upload files by making a custom HTTP request.

- 18,928
- 4
- 42
- 62
-
Is there such an easy way to restrict file size too? I know how to do it with JS/jQuery, would be nice to know though. – sandrooco Oct 27 '15 at 15:02
-
3@Sandesire I don't think that you can restrict file sizes in HTML. It's possible using JavaScript, as you suggested. – Sachin Joseph Nov 10 '15 at 12:39
-
2From my personal experience this looks like a good answer, the mime type alone will not work on all browsers. – Christophe Roussy Sep 25 '18 at 12:28
-
2Incidentally `accept` still doesn't work in Edge: https://stackoverflow.com/questions/31875617/input-accept-attribute-in-microsoft-edge#32214646. More details here: https://wpdev.uservoice.com/forums/257854-microsoft-edge-developer/suggestions/13661175-full-spec-support-for-accept-in-input-type-file – SharpC Jan 29 '19 at 16:43
-
You're right more or less. Edge doesn't select the filter as the default filter in the file select dialog box; the filter appears at the bottom end of the list. :-) – Sachin Joseph Jan 29 '19 at 23:14
-
5I wish we had a choice to exclude files as well, for example `exclude="exe"`. ¯\_(ツ)_/¯ – Sagiv b.g Feb 19 '19 at 16:11
-
3To clarify Edge behavior further (according to my tests), it will add different filters based on what you specify, but a) it's not bundled, so it will list each extension as a separate option and b) it will always add some in-build extensions such as .html, and c) as already stated, it will always pre-select (*). Which makes it a big mess and useless in most cases. I voted on the uservoice link, let's hope they listen sooner or later. – Arie Sep 27 '19 at 13:45
-
The file type filter dropdown shows the **All files (*)** as default one. Based on your answer, I will get xls and xlsx formats. But still user can change it to default one. – Himabindu Feb 25 '22 at 06:25
There is the accept attribute for the input tag. However, it is not reliable in any way. Browsers most likely treat it as a "suggestion", meaning the user will, depending on the file manager as well, have a pre-selection that only displays the desired types. They can still choose "all files" and upload any file they want.
For example:
<form>
<input type="file" name="pic" id="pic" accept="image/gif, image/jpeg" />
</form>
Read more in the HTML5 spec
Keep in mind that it is only to be used as a "help" for the user to find the right files. Every user can send any request he/she wants to your server. You always have to validated everything server-side.
So the answer is: no you cannot restrict, but you can set a pre-selection but you cannot rely on it.
Alternatively or additionally you can do something similar by checking the filename (value of the input field) with JavaScript, but this is nonsense because it provides no protection and also does not ease the selection for the user. It only potentially tricks a webmaster into thinking he/she is protected and opens a security hole. It can be a pain in the ass for users that have alternative file extensions (for example jpeg instead of jpg), uppercase, or no file extensions whatsoever (as is common on Linux systems).

- 1
- 1

- 29,118
- 24
- 122
- 168
-
3for additional information see http://stackoverflow.com/questions/181214/file-input-accept-attribute-is-it-useful – Martin Meeser Jul 23 '13 at 15:10
-
1Although it is true that's it's impossible to prevent the user from selecting ANY type of file eventually, these days you can take advantage of the HTML5 File API and work with the selected file for upload, before it is actually uploaded to the server, including detecting its type, size and more. Give it a try. It's very easy to use, yet very powerful and useful. – TheCuBeMan May 08 '17 at 12:47
You can use the change
event to monitor what the user selects and notify them at that point that the file is not acceptable. It does not limit the actual list of files displayed, but it is the closest you can do client-side, besides the poorly supported accept
attribute.
var file = document.getElementById('someId');
file.onchange = function(e) {
var ext = this.value.match(/\.([^\.]+)$/)[1];
switch (ext) {
case 'jpg':
case 'bmp':
case 'png':
case 'tif':
alert('Allowed');
break;
default:
alert('Not allowed');
this.value = '';
}
};
<input type="file" id="someId" />

- 3,273
- 2
- 17
- 16

- 191,379
- 34
- 261
- 317
-
11@joe, it is an example... it can extend to whatever extensions you want to allow. – Gabriele Petrioli Dec 01 '10 at 22:07
-
yeah, you can. but you DIDN'T! and maby somebody copied it already! and what about files with correct mime type but no extension? – The Surrican Dec 01 '10 at 22:09
-
53@Joe .. well .. i try to provide direction and a sound logic. Not fully implemented solutions for every case. I trust the viewers to use common sense when copy/pasting code from the web ;) – Gabriele Petrioli Dec 01 '10 at 23:59
-
7How about "Some.File.jpg"? Perhaps that regex line needs to read: var ext = this.value.match(/\.([^.]+)$/)[1]; – Jon Marnock Mar 13 '13 at 04:43
-
1Issue with this approach is that something could still technically be a jpeg even if it doesn't end with that extension. Extensions !== mime types – Matt Fletcher Sep 11 '19 at 11:11
-
1I use a FileReader and file input element with an extra if else statement. I use this example and it works perfectly. The code is clean and easy to understand. The accept function for the file element doesn't really work. I need to allow m3u and m3u8 files. Many web browsers work individual at the accept function for the file element. – AxelS Jul 10 '23 at 23:01
Yes, you are right. It's impossible with HTML. User will be able to pick whatever file he/she wants.
You could write a piece of JavaScript code to avoid submitting a file based on its extension. But keep in mind that this by no means will prevent a malicious user to submit any file he/she really wants to.
Something like:
function beforeSubmit()
{
var fname = document.getElementById("ifile").value;
// check if fname has the desired extension
if (fname hasDesiredExtension) {
return true;
} else {
return false;
}
}
HTML code:
<form method="post" onsubmit="return beforeSubmit();">
<input type="file" id="ifile" name="ifile"/>
</form>

- 176,835
- 32
- 241
- 292
-
1Thank you :-) I actually already have that code to limit the type, but good suggestion! – Bojangles Dec 01 '10 at 20:48
-
3there is a fully valid html attribute for that so it is possible. it is just not respected by browsers, but thats a standardization problem. as well as any stuff handled client side in unprotected markup cannot restricted anything java script is no solution. – The Surrican Dec 01 '10 at 20:55
-
2Very good point. I will add a second PHP checker just in case. Can't be too careful! – Bojangles Dec 01 '10 at 20:57
-
js validation is no protection whatsoever. it does not ease the selection for the user by displaying only relevant files. it is just unnecessary code with the potential to be a pain in the ass for users that for example have 4 letter or uppercase file extensions which you didnt take care of in your script. or trick some webmaster into thinking he/she is protected. i cant see any good in this method. you can youse the html attribute to ease the selectino for the user if its supported and you must do the validation server side. this here can only save some bandwith. – The Surrican Dec 01 '10 at 21:02
-
2Well, it does no harm if I'm using a PHP validation script too, so I'll use both. – Bojangles Dec 01 '10 at 21:05
-
19@Joe: stop saying that my answer sucks! :-) Anyway, it's not a perfect solution. As I said in the beginning of it: "it's impossible" to do what OP wants. But you can have **some** degree of help for the user if you only let him/her choose files with certain extensions. **REAL** file type validation must be done **server side**. – Pablo Santa Cruz Dec 01 '10 at 21:05
-
1it does harm. because somebody might rely on it and forget the server side validation. and why have it redundant if its not reliable? and it is also a potential pain in the ass for the user. the only point i see in it is to save bandwidth by blocking the upload before it happens. – The Surrican Dec 01 '10 at 21:13
-
here is the best example: http://stackoverflow.com/questions/4328947/limit-file-format-when-using-input-typefile/4329103#4329103 -> now your file may be named "me.jpeg". it is blocked altough its perfectly valid and you may end up with a frustrated user that quites your site because he/she cannot upload his/her profile picture – The Surrican Dec 01 '10 at 21:15
-
13@JoeHopfgartner : Dude, you're being overly harsh for Pablo here. clientside validation is done in tons of places and although not foolproof (there should [b]always[/b] be serverside validation included) it can save the user quite some time (no postback for a stupid extension check etc). While the script given by Pablo is not perfect, it is merely intended to be an example of how to tackle this issue... Maybe you should email the tech guys at Microsoft and ask them to remove Clientside validation from their ASP.NET validators since it's all plain rubbish to you... – Nathan Aug 20 '12 at 13:44
-
1
Technically you can specify the accept
attribute (alternative in html5) on the input
element, but it's not properly supported.

- 174,988
- 54
- 320
- 367
-
W3Schools browser support fail! It's a shame really. It is also a security concern - people can hack past client side code and upload whatever they want. – Bojangles Dec 01 '10 at 20:58
-
6True, it's best not to use this for security, but it definitely helps usability on browsers that support it. Users are shown only the files that the site allows (not all the other junk they might have in the same folder) and they don't have to go through the whole upload process to be given an error, they will know straight away. Coders *should* use this. – Simon East May 22 '12 at 05:45
You can use the "accept" attribute as a filter in the file select box. Using "accept" help you filter input files based on their "suffix" or their "MIME type"
1.Filter based on suffix: Here "accept" attribute just allow to select files with .jpeg extension.
<input type="file" accept=".jpeg" />
2.Filter based on "file type" Here the "accept" attribute just allows you to select a file with "image/jpeg" type.
<input type="file" accept="image/jpeg" />
Important: We can change or delete the extension of a file, without changing the meme type. For example it is possible to have a file without extension, but the type of this file can be "image/jpeg". So this file can not pass the accept=".jpeg" filter. but it can pass accept="image/jpeg".
3.We can use * to select all kinds of file types. For example below code allows to select all kinds of images. for example "image/png" or "image/jpeg" or ... . All of them are allowed.
<input type="file" accept="image/*" />
4.We can use cama ( , ) as an "or operator" in the select attribute. For example to allow all kind of images or pdf files we can use this code:
<input type="file" accept="image/* , application/pdf" />

- 631
- 6
- 10
Use input
tag with accept
attribute
<input type="file" name="my-image" id="image" accept="image/gif, image/jpeg, image/png" />
Click here for the latest browser compatibility table
Live demo here
To select only image files, you can use this accept="image/*"
<input type="file" name="my-image" id="image" accept="image/*" />
Live demo here
Only gif, jpg and png will be shown, screen grab from Chrome version 44

- 32,342
- 7
- 71
- 76
-
Thanks! In Chrome on Win10, if I use `accept="image/*"`, it says "Image Files" instead of "Custom Files" in the file picker, which is nice for the end user. – Teddy Sep 14 '16 at 12:22
-
-
@PrashantPrajapati Yes, thats how browsers are made, there should be corresponding validation in server.Browser functionality is just for better user experience. – kiranvj Jun 07 '19 at 14:37
I know this is a bit late.
function Validatebodypanelbumper(theForm)
{
var regexp;
var extension = theForm.FileUpload.value.substr(theForm.FileUpload1.value.lastIndexOf('.'));
if ((extension.toLowerCase() != ".gif") &&
(extension.toLowerCase() != ".jpg") &&
(extension != ""))
{
alert("The \"FileUpload\" field contains an unapproved filename.");
theForm.FileUpload1.focus();
return false;
}
return true;
}

- 363
- 3
- 11
As mentioned in previous answers we cannot restrict user to select files for only given file formats. But it's really handy to use the accept tag on file attribute in html.
As for validation, we have to do it at the server side. We can also do it at client side in js but its not a foolproof solution. We must validate at server side.
For these requirements I really prefer struts2 Java web application development framework. With its built-in file upload feature, uploading files to struts2 based web apps is a piece of cake. Just mention the file formats that we would like to accept in our application and all the rest is taken care of by the core of framework itself. You can check it out at struts official site.

- 18,928
- 4
- 42
- 62

- 499
- 5
- 7
You could actually do it with javascript but remember js is client side, so you would actually be "warning users" what type of files they can upload, if you want to AVOID (restrict or limit as you said) certain type of files you MUST do it server side.
Look at this basic tut if you would like to get started with server side validation. For the whole tutorial visit this page.
Good luck!

- 13,917
- 6
- 60
- 87

- 39,971
- 43
- 126
- 190
I may suggest following:
If you have to make user select any of image files by default, the use accept="image/*"
<input type="file" accept="image/*" />
if you want to restrict to specific image types then use accept="image/bmp, image/jpeg, image/png"
<input type="file" accept="image/bmp, image/jpeg, image/png" />
if you want to restrict to specific types then use accept=".bmp, .doc, .pdf"
<input type="file" accept=".bmp, .doc, .pdf" />
You cannot restrict user to change file filer to all files, so always validate file type in script and server

- 11,779
- 2
- 16
- 17
-
1This was what I was looking for: accept=".bmp" Works fine on chrome. – MichaelRom Mar 13 '20 at 17:04
Building on the previous answers of using the accept attribute, you can accomplish this using the File API. This also gives you access to the file contents should you use FileReader to do some local parsing or data handling.
First create an input element, here you could apply the file type to the accept attribute but for the example it will allow you to select all file types.
<input type="file" name="upload" accept="*" multiple>
Next we need to listen to the 'change' event on the input element.
var upload = document.querySelector('input[type="file"]');
upload.addEventListener('change', function() {});
Inside the function you'll be able to access the files object of the input.
var files = this.files
We can't just iterate over the object since it isn't an array, however we can use the item() function to access our File object from the list.
for (var i = 0; i < files.length; i++) {
var file = files.item(i);
}
Now that we have our File object, we can access its name and type properties and do our file check here. In this case I'm checking to see if it's a .txt file and printing a message if it isn't. You can check the name against a regex pattern for the file type or check the type against its MIME type.
if (!file.name.match(/.txt$/i) || file.type != 'text/plain') {
console.log(file.name + ' is not a .txt file.');
}
var upload = document.querySelector('input[type="file"]');
upload.addEventListener('change', function() {
var files = this.files;
for (var i = 0; i < files.length; i++) {
var file = files.item(i);
if (!file.name.match(/.txt$/i) || file.type != 'text/plain') {
console.log(file.name + ' is not a .txt file.');
}
}
});
<input type="file" name="upload" accept="*" multiple>
File API is very well supported for modern browsers. By combining this with the accept attribute you can easily filter what the local user can select in an upload and provide useful feedback. If you are uploading the file, you should still check and validate the file type on your backend.

- 121
- 6