<input type="file"> limit selectable files by extensions [duplicate]
Asked Answered
G

4

152

How can someone limit the files that can be selected with the input type="file" element by extensions?

I already know the accept attribute, but in chrome it does limit the files by the last MIME Type defined (in this case "gif") and FF4 does not even limit anything.

<input type="file" accept="image/jpg, image/gif">

Am I doing anything wrong or is there another way?

Gervase answered 26/4, 2011 at 21:14 Comment(0)
L
21

Honestly, the best way to limit files is on the server side. People can spoof file type on the client so taking in the full file name at server transfer time, parsing out the file type, and then returning a message is usually the best bet.

Lionel answered 26/4, 2011 at 21:15 Comment(10)
+1. Also I recommend putting something in your server side code to stop the upload if the received file is too large.Tubuliflorous
thx ... i made it serversided.Gervase
@JoshuaCarmody how do you suggest to do it for large files(2gb and above) on server side?Infantilism
@Allan Depends a lot on the tech. ASP.NET has a "max request size" that you can specify in the Web.config. Writing a handler that reads the request from an input stream and stops after a certain number of bytes is possible in other languages. Really depends on your app. Post a separate question if you'd like more details.Tubuliflorous
+1, but note: this answer is vaguely stale, since the HTML5 File API allows more file work to be done client side. I, for example, am not sending the file upstream, I'm loading the text into a textarea. The fact remains, that the server should be vigilant any time it receives a file.Kielty
I think it's better to do both. Giving the user feedforward about the files that are(n't) selectable, will save some frustrations. Because if the users spends half a minute precisely selecting files he needs, and afterwards finds out it's all for nothing.. The earlier you can tel hem, the better.Algeria
-1. Good suggestion, but the question didn't suggest the files would be uploaded anywhere. It didn't even suggest the presence of a server at all (such as in the case of a fully client-side app). As said already, this answer should be a comment instead.Jarmon
Serverside is good, but also means the file got sent to server already, your wasting time and traffic if you can easily prevent on the client. Better to have some client side validation as wellRm
What if you want to show error before uploading? Checking on server is a must but preventing from client could be good for user experienceFlyleaf
Checking on server side is good for security but not for UX so we should have either somehting in front-end that warn user wich file we want and then we confirm in the back.Sinfonia
T
381

Easy way of doing it would be:

<input type="file" accept=".gif,.jpg,.jpeg,.png,.doc,.docx">

Works with all browsers, except IE9. I haven't tested it in IE10+.

Terry answered 4/2, 2014 at 22:59 Comment(11)
accept does not work in Firefox (as of 31.0 and 32.0)Railey
Test in FF 37.0. Works fine!.Ragged
this seems perfectly valid according to the MDN docsBriquet
Under the "accept" of a file input, there can also be a definition of the general type of the files for selection. For example, if you put "image/*" under the "accept" attribute, the limitation will cover all the standard file formats (gif, jpeg and so on) for images and not just the type(s) by extensions. In addition, you can combine the pre-defined type(s) and extensions. For example: "image/*,.swf". For this example, the limitation will include all standard image files AND all ".swf" files. NOTE: the user can always select "All Files" from the type list in the dialog box... ;-)Matherne
This helps to provide some filtering to the file dialog on uploads, but I definitely think this needs to be used in conjunction with a server restriction too.Takeo
tanks ,its work with Firefox 57.0.4 (64-bit)Abecedary
i beliefe the user can forge his own post-method, bypassing your accept. this looks nice at first sight, but safer is always cheking @ serversideBloomfield
@Bloomfield input check and security should always be implemented on the server side. The accept feature exists only to help users quickly filter relevant files and not having to sift through thousands of irrelevant files.Contrabandist
This answer is better than what is on w3schools, thanks!Incommunicative
This solution will just be a filtering files option only. Incase user select all, user can see all file and select any file user want.Anchylose
accept="image/*"Pastorale
T
30

NOTE: This answer is from 2011. It was a really good answer back then, but as of 2015, native HTML properties are supported by most browsers, so there's (usually) no need to implement such custom logic in JS. See Edi's answer and the docs.


Before the file is uploaded, you can check the file's extension using Javascript, and prevent the form being submitted if it doesn't match. The name of the file to be uploaded is stored in the "value" field of the form element.

Here's a simple example that only allows files that end in ".gif" to be uploaded:

<script type="text/javascript">
    function checkFile() {
        var fileElement = document.getElementById("uploadFile");
        var fileExtension = "";
        if (fileElement.value.lastIndexOf(".") > 0) {
            fileExtension = fileElement.value.substring(fileElement.value.lastIndexOf(".") + 1, fileElement.value.length);
        }
        if (fileExtension.toLowerCase() == "gif") {
            return true;
        }
        else {
            alert("You must select a GIF file for upload");
            return false;
        }
    }
</script>

<form action="upload.aspx" enctype="multipart/form-data" onsubmit="return checkFile();">
    <input name="uploadFile" id="uploadFile" type="file" />

    <input type="submit" />
</form>

However, this method is not foolproof. Sean Haddy is correct that you always want to check on the server side, because users can defeat your Javascript checking by turning off javascript, or editing your code after it arrives in their browser. Definitely check server-side in addition to the client-side check. Also I recommend checking for size server-side too, so that users don't crash your server with a 2 GB file (there's no way that I know of to check file size on the client side without using Flash or a Java applet or something).

However, checking client side before hand using the method I've given here is still useful, because it can prevent mistakes and is a minor deterrent to non-serious mischief.

Tubuliflorous answered 26/4, 2011 at 21:31 Comment(3)
This is the best answer. Even though it's understood that you definitely need to check files properly on the server side, this client side JS check is good for usability - means you can warn the user early of a probable error.Cutback
you're gonna want to have a toLowerCase() in there before the comparisonZelmazelten
With IE You can check the file size using the Scripting.FileSystemObject but you need to allow for unsafe ActiveX in the client browser. So yes there is no "good" way.Mafalda
L
21

Honestly, the best way to limit files is on the server side. People can spoof file type on the client so taking in the full file name at server transfer time, parsing out the file type, and then returning a message is usually the best bet.

Lionel answered 26/4, 2011 at 21:15 Comment(10)
+1. Also I recommend putting something in your server side code to stop the upload if the received file is too large.Tubuliflorous
thx ... i made it serversided.Gervase
@JoshuaCarmody how do you suggest to do it for large files(2gb and above) on server side?Infantilism
@Allan Depends a lot on the tech. ASP.NET has a "max request size" that you can specify in the Web.config. Writing a handler that reads the request from an input stream and stops after a certain number of bytes is possible in other languages. Really depends on your app. Post a separate question if you'd like more details.Tubuliflorous
+1, but note: this answer is vaguely stale, since the HTML5 File API allows more file work to be done client side. I, for example, am not sending the file upstream, I'm loading the text into a textarea. The fact remains, that the server should be vigilant any time it receives a file.Kielty
I think it's better to do both. Giving the user feedforward about the files that are(n't) selectable, will save some frustrations. Because if the users spends half a minute precisely selecting files he needs, and afterwards finds out it's all for nothing.. The earlier you can tel hem, the better.Algeria
-1. Good suggestion, but the question didn't suggest the files would be uploaded anywhere. It didn't even suggest the presence of a server at all (such as in the case of a fully client-side app). As said already, this answer should be a comment instead.Jarmon
Serverside is good, but also means the file got sent to server already, your wasting time and traffic if you can easily prevent on the client. Better to have some client side validation as wellRm
What if you want to show error before uploading? Checking on server is a must but preventing from client could be good for user experienceFlyleaf
Checking on server side is good for security but not for UX so we should have either somehting in front-end that warn user wich file we want and then we confirm in the back.Sinfonia
C
1
 function uploadFile() {
     var fileElement = document.getElementById("fileToUpload");
        var fileExtension = "";
        if (fileElement.value.lastIndexOf(".") > 0) {
            fileExtension = fileElement.value.substring(fileElement.value.lastIndexOf(".") + 1, fileElement.value.length);
        }
        if (fileExtension == "odx-d"||fileExtension == "odx"||fileExtension == "pdx"||fileExtension == "cmo"||fileExtension == "xml") {
         var fd = new FormData();
        fd.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
        var xhr = new XMLHttpRequest();
        xhr.upload.addEventListener("progress", uploadProgress, false);
        xhr.addEventListener("load", uploadComplete, false);
        xhr.addEventListener("error", uploadFailed, false);
        xhr.addEventListener("abort", uploadCanceled, false);
        xhr.open("POST", "/post_uploadReq");
        xhr.send(fd);
        }
        else {
            alert("You must select a valid odx,pdx,xml or cmo file for upload");
            return false;
        }
       
      }

tried this , works very well

Casaba answered 23/1, 2014 at 15:24 Comment(1)
If you are uploading files, remember to also validate file types on the server, as client-side validation can be bypassed.Jarmon

© 2022 - 2024 — McMap. All rights reserved.