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.
The <input type="file"> defines a file-select field and a "Browse" button for file uploads. To define a file-select field that allows multiple files to be selected, add the multiple attribute. Tip: Always add the <label> tag for best accessibility practices!
Use two <input type=file> elements instead, without the multiple attribute. If the requirement is really just "have two different single inputs", then this is actually the best answer @Diego.
You can't. The only way to set the value of a file input is by the user to select a file. This is done for security reasons. Otherwise you would be able to create a JavaScript that automatically uploads a specific file from the client's computer.
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).
Strictly speaking, the answer is no. A developer cannot prevent a user from uploading files of any type or extension.
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.
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" />
JSFiddle
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With