155

I used <input type= "file" name="Upload" >

Now I would like to restrict this by accepting only .pdf and .xls files.

When I click the submit button it should validate this.

And when I click the files (PDF/XLS) on webpage it should automatically open.

Could anyone please give some examples for this?

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
Manikandan
  • 1,589
  • 3
  • 11
  • 10

10 Answers10

297

You could do so by using the attribute accept and adding allowed mime-types to it. But not all browsers do respect that attribute and it could easily be removed via some code inspector. So in either case you need to check the file type on the server side (your second question).

Example:

<input type="file" name="upload" accept="application/pdf,application/vnd.ms-excel" />

To your third question "And when I click the files (PDF/XLS) on webpage it automatically should open.":

You can't achieve that. How a PDF or XLS is opened on the client machine is set by the user.

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
feeela
  • 29,399
  • 7
  • 59
  • 71
  • Hi feeela When i upload the files it will be store in server. I heard so that it is possible by javascript functions to open .pdf and .xls files by clicking the files on browser... – Manikandan Aug 27 '12 at 13:38
  • thats it ! Both sides client and server explained. Great answer –  Aug 22 '16 at 09:24
  • 4
    if you list all files on selection box. you can still uploading any file. – rüff0 Jan 05 '19 at 15:35
90

you can use this:

HTML

<input name="userfile" type="file" accept="application/pdf, application/vnd.ms-excel" />

support only .PDF and .XLS files

Radames E. Hernandez
  • 4,235
  • 27
  • 37
23

You can try following way

<input type= "file" name="Upload" accept = "application/pdf,.csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel">

OR (in asp.net mvc)

@Html.TextBoxFor(x => x.FileName, new { @id = "doc", @type = "file", @accept = "application/pdf,.csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" })
Marvin
  • 853
  • 2
  • 14
  • 38
20

Unfortunately, there is no guaranteed way to do it at time of selection.

Some browsers support the accept attribute for input tags. This is a good start, but cannot be relied upon completely.

<input type="file" name="pic" id="pic" accept="image/gif, image/jpeg" />

You can use a cfinput and run a validation to check the file extension at submission, but not the mime-type. This is better, but still not fool-proof. Files on OSX often have no file extensions or users could maliciously mislabel the file types.

ColdFusion's cffile can check the mime-type using the contentType property of the result (cffile.contentType), but that can only be done after the upload. This is your best bet, but is still not 100% safe as mime-types could still be wrong.

Joe C
  • 3,506
  • 2
  • 21
  • 32
  • 3
    Please, never ever check a file based on the extension. What about a executable named lolcat.jpg? – feeela Aug 27 '12 at 13:14
  • 1
    I think what phantom42 is trying to say here is that you should check extension and MIME type on the server. The `accept` attribute on the `input` tag can be added but is not 100% effective. – Chris Peters Aug 27 '12 at 13:15
  • I 100% agree. It cannot be relied upon, but I find it OK as a first-line of defense in conjunction with the cffile.contenttype. – Joe C Aug 27 '12 at 13:16
  • Hi Phantom As you said this accept is only works in chrome not in IE. Is there anyother way to do this which will be support by all browser – Manikandan Aug 27 '12 at 13:36
  • Unfortunately, no; that's why I said it cannot be relied upon and must be used in conjunction with the other methods if you use it at all. – Joe C Aug 27 '12 at 13:39
  • As phantom said - no guarantees. Anything you do on the client side can (and will) be circumvented. Make sure you are controlling this input on the server side. Server side = security, client side = user experience. Mark's rule of thumb. – Mark A Kruger Aug 27 '12 at 14:35
  • For JPG images, we will have to write "image/jpeg" instead of "image/jpg". Thanks for asking this question. – Kamlesh Sep 12 '19 at 15:22
5

You could use JavaScript. Take in consideration that the big problem with doing this with JavaScript is to reset the input file. Well, this restricts to only JPG (for PDF you will have to change the mime type and the magic number):

<form id="form-id">
  <input type="file" id="input-id" accept="image/jpeg"/>
</form>

<script type="text/javascript">
    $(function(){
        $("#input-id").on('change', function(event) {
            var file = event.target.files[0];
            if(file.size>=2*1024*1024) {
                alert("JPG images of maximum 2MB");
                $("#form-id").get(0).reset(); //the tricky part is to "empty" the input file here I reset the form.
                return;
            }

            if(!file.type.match('image/jp.*')) {
                alert("only JPG images");
                $("#form-id").get(0).reset(); //the tricky part is to "empty" the input file here I reset the form.
                return;
            }

            var fileReader = new FileReader();
            fileReader.onload = function(e) {
                var int32View = new Uint8Array(e.target.result);
                //verify the magic number
                // for JPG is 0xFF 0xD8 0xFF 0xE0 (see https://en.wikipedia.org/wiki/List_of_file_signatures)
                if(int32View.length>4 && int32View[0]==0xFF && int32View[1]==0xD8 && int32View[2]==0xFF && int32View[3]==0xE0) {
                    alert("ok!");
                } else {
                    alert("only valid JPG images");
                    $("#form-id").get(0).reset(); //the tricky part is to "empty" the input file here I reset the form.
                    return;
                }
            };
            fileReader.readAsArrayBuffer(file);
        });
    });
</script>

Take in consideration that this was tested on latest versions of Firefox and Chrome, and on IExplore 10.

For a complete list of mime types see Wikipedia.

For a complete list of magic number see Wikipedia.

Sevle
  • 3,109
  • 2
  • 19
  • 31
lmiguelmh
  • 3,074
  • 1
  • 37
  • 53
4

I would filter the files server side, because there are tools, such as Live HTTP Headers on Firefox that would allow to upload any file, including a shell. People could hack your site. Do it server site, to be safe.

Alexandre Hitchcox
  • 2,704
  • 5
  • 22
  • 33
1

If you want the file upload control to Limit the types of files user can upload on a button click then this is the way..

<script type="text/JavaScript">
<!-- Begin
function TestFileType( fileName, fileTypes ) {
if (!fileName) return;

dots = fileName.split(".")
//get the part AFTER the LAST period.
fileType = "." + dots[dots.length-1];

return (fileTypes.join(".").indexOf(fileType) != -1) ?
alert('That file is OK!') : 
alert("Please only upload files that end in types: \n\n" + (fileTypes.join(" .")) + "\n\nPlease select a new file and try again.");
}
// -->
</script>

You can then call the function from an event like the onClick of the above button, which looks like:

onClick="TestFileType(this.form.uploadfile.value, ['gif', 'jpg', 'png', 'jpeg']);"

You can change this to: PDF and XLS

You can see it implemented over here: Demo

Vishal Suthar
  • 17,013
  • 3
  • 59
  • 105
  • Thanks Vishal Suthar. I think this logic surely help me to go forward. – Manikandan Aug 28 '12 at 07:22
  • It's my pleasure..It will sure help but still no upvote..??@Manikandan – Vishal Suthar Aug 28 '12 at 07:46
  • Still i have one more doubt. I tried to restrict the files (PDF&Xls.xlsx only) in input type=file. But it works fine in Google Chrome.. But i'm unable to do this in IE. Is there any solution to make restrict the files in IE? If yes Please make me to go in correct way. – Manikandan Aug 28 '12 at 07:52
  • I just checked (http://www.codestore.net/store.nsf/unid/DOMM-4Q8H9E/) in IE and it works fine..@Manikandan – Vishal Suthar Aug 28 '12 at 08:18
  • Is comparison to the `accept`-attribute, this method does not narrow down folder contents to selected file-types when selecting a file on the local machine. – feeela Aug 28 '12 at 08:42
  • @vishal: Yours is fine. OK. But my intention is .The above only will display the files of pdf,xls,xlsx type when you click the "Choose File"... This works only in Chrome.. Not in IE.. I need an alternate solution for this.. I hope now you have understood.. – Manikandan Aug 28 '12 at 08:52
1

While this particular example is for a multiple file upload, it gives the general information one needs:

https://developer.mozilla.org/en-US/docs/DOM/File.type

As far as acting upon a file upon /download/ this is not a Javascript question -- but rather a server configuration. If a user does not have something installed to open PDF or XLS files, their only choice will be to download them.

Jeremy J Starcher
  • 23,369
  • 6
  • 54
  • 74
0

put your MIME type in the accept attribute

search for your file extension MIME type from here : https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types

mahmoud elgml
  • 161
  • 1
  • 6
-9

Try this one:-

              <MyTextField
                id="originalFileName"
                type="file"
                inputProps={{ accept: '.xlsx, .xls, .pdf' }}
                required
                label="Document"
                name="originalFileName"
                onChange={e => this.handleFileRead(e)}
                size="small"
                variant="standard"
              />
Ankit Kumar Rajpoot
  • 5,188
  • 2
  • 38
  • 32