The html5 file api provides lots of new features which can be used to read files on clientside from within the browser.
Lets take a look at this Demo first :
This file upload control will only take zip or png files which are less than 1MB in size. For any other files it will show an error message.
And this functionality if purely clientside. No server interaction or uploads yet.
Code
Html
<input type="file" data-file_type="zip|png" data-max_size="1000000">
As we can see above , the validation parameters are stored inside the input tag itself using custom data tags. So allowed file types are zip and png , and allowed maximum size is 1000000 bytes , that is nearly 1 MB.
Javascript
Data attributes are used to specify the allowed file types and the maximum size of the upload file. The extensions are used to map to a list of mime types (later in this article).
$('input[type=file]').each(function() { if(typeof $(this).attr('data-file_type') == 'string') { var file_types = $(this).attr('data-file_type').split('|'); } var mimes = get_mimes(file_types); var max_size = parseInt($(this).attr('data-max_size')); $(this).change(function(evt) { var finput = $(this); var files = evt.target.files; // FileList object // files is a FileList of File objects. List some properties. var output = []; for (var i = 0, f; f = files[i]; i++) { //Check mime type if(jQuery.inArray(f.type , mimes) == -1) { alert('File type '+ f.type + ' not allowed'); $(this).val(''); continue; } //Check size else if(f.size > max_size) { alert('Maximum file size is ' + max_size + ' bytes.'); $(this).val(''); } //Validation ok else { output.push('<strong>', f.name, '</strong> (', f.type || 'n/a', ') - ', f.size, ' bytes, last modified: ', f.lastModifiedDate.toLocaleDateString() ); } } finput.after('<div>' + output.join('') + '</div>'); }); });
The above code uses jquery.
In html5 capable browsers when a file is selected for upload in a file input , then the input element has a Filelist object in its files attribute which is an object of type FileList
(which is a Collection of File
objects).
Information about each file can be retrieved like this :
var files = evt.target.files; // FileList object var file_count = files.length; var file_1 = files[0]; // or files.item(0); var name = file_1.name; var size = file_1.size; var type = file_1.type; var lastModifiedDate = file_1.lastModifiedDate;
The things to check are file type and file size. That is all that can be checked.
The type variable contains the mime type of the file. So we have an existing list of mime types useful for the purpose.
List of mimes
var mime_types = { "hqx":"application/mac-binhex40", "cpt":"application/mac-compactpro", "csv":["text/x-comma-separated-values","text/comma-separated-values","application/octet-stream","text/csv","application/csv"], "bin":"application/macbinary", "dms":"application/octet-stream", "lha":"application/octet-stream", "lzh":"application/octet-stream", "exe":"application/octet-stream", "class":"application/octet-stream", "psd":"application/x-photoshop", "so":"application/octet-stream", "sea":"application/octet-stream", "dll":"application/octet-stream", "oda":"application/oda", "pdf":["application/pdf","application/x-download"], "ai":"application/postscript", "eps":"application/postscript", "ps":"application/postscript", "smi":"application/smil", "smil":"application/smil", "mif":"application/vnd.mif", "xls":["application/excel","application/vnd.ms-excel","application/msexcel"], "ppt":["application/powerpoint","application/vnd.ms-powerpoint"], "wbxml":"application/wbxml", "wmlc":"application/wmlc", "dcr":"application/x-director", "dir":"application/x-director", "dxr":"application/x-director", "dvi":"application/x-dvi", "gtar":"application/x-gtar", "gz":"application/x-gzip", "php":"application/x-httpd-php", "php4":"application/x-httpd-php", "php3":"application/x-httpd-php", "phtml":"application/x-httpd-php", "phps":"application/x-httpd-php-source", "js":"application/x-javascript", "swf":"application/x-shockwave-flash", "sit":"application/x-stuffit", "tar":"application/x-tar", "tgz":"application/x-tar", "xhtml":"application/xhtml+xml", "xht":"application/xhtml+xml", "zip":["application/x-zip","application/zip","application/x-zip-compressed"], "mid":"audio/midi", "midi":"audio/midi", "mpga":"audio/mpeg", "mp2":"audio/mpeg", "mp3":["audio/mpeg", "audio/mpg"], "aif":"audio/x-aiff", "aiff":"audio/x-aiff", "aifc":"audio/x-aiff", "ram":"audio/x-pn-realaudio", "rm":"audio/x-pn-realaudio", "rpm":"audio/x-pn-realaudio-plugin", "ra":"audio/x-realaudio", "rv":"video/vnd.rn-realvideo", "wav":"audio/x-wav", "bmp":"image/bmp", "gif":"image/gif", "jpeg":["image/jpeg","image/pjpeg"], "jpg":["image/jpeg","image/pjpeg"], "jpe":["image/jpeg","image/pjpeg"], "png":["image/png","image/x-png"], "tiff":"image/tiff", "tif":"image/tiff", "css":"text/css", "html":"text/html", "htm":"text/html", "shtml":"text/html", "txt":"text/plain", "text":"text/plain", "log":["text/plain","text/x-log"], "rtx":"text/richtext", "rtf":"text/rtf", "xml":"text/xml", "xsl":"text/xml", "mpeg":"video/mpeg", "mpg":"video/mpeg", "mpe":"video/mpeg", "qt":"video/quicktime", "mov":"video/quicktime", "avi":"video/x-msvideo", "movie":"video/x-sgi-movie", "doc":"application/msword", "docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document", "xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "word":["application/msword","application/octet-stream"],"xl":"application/excel","eml":"message/rfc822" };
The above list of mime types can give the mime type of a give extension like zip or png. Next we have a function that provides the list of allowed mimes as an array :
/* Get the mimes of a list of extensions as an array */ function get_mimes(extensions) { var mimes = []; for(var i in extensions) { var ext = extensions[i]; if(ext in mime_types) { var mime = mime_types[ext]; if($.isArray(mime)) { jQuery.merge(mimes , mime); } else { mimes.push(mime); } } } return mimes; }
This method can be used like this get_mimes(['zip' , 'png']) and it will return an array of mimes for the given extensions. This return values is used in the validation part to simply check if the mime of the selected file is there in this list or not. If not , then show error.
References :
The documentation of the file api lies here : http://www.w3.org/TR/file-upload/.
Details of browser support are available here : http://caniuse.com/#search=file api