HTML5 drag file type check

I would like to change the background color of the call area to green or red, depending on whether the contained drag and drop contains the payload supported file types (JPEG).

  • Does Gecko and Webkit support file type drag and drop?

  • How can I extract the file type in these two browsers?

I found the event.dataTransfer.types API, but for Firefox, it seems to be populated with application / x-moz-file , and so I think I'm doing something wrong.

+7
source share
3 answers

You can get file types in the Gecko and webkit browsers using a file object.

var files =e.dataTransfer.files||e.target.files; // File list 

A file object returns a name, type, and size. You can also get the last modified date.

 var mimeType= files[0].type; //mime type of file list first entry 
+11
source

Testing the file type in JavaScript is a bit of work, but newer versions of browsers now have a FileReader object that allows this.

There is an incomplete reference to my implementation, which reads the buffer as uint8 bytes, and then checks if the input is valid JPEG, GIF, PNG. Obviously, this will increase over time. For a more complete version, find the editor.js file in the editor.js editor of the snapwebsites project. https://sourceforge.net/p/snapcpp/code/ci/master/tree/snapwebsites/plugins/editor/

 // The buffer is expected to be an ArrayBuffer() as read with a FileReader _buffer2mime: function(buffer) { buf = Uint8Array(buffer); if(buf[0] == 0xFF && buf[1] == 0xD8 && buf[2] == 0xFF && buf[3] == 0xE0 && buf[4] == 0x00 && buf[5] == 0x10 && buf[6] == 0x4A // J && buf[7] == 0x46 // F && buf[8] == 0x49 // I && buf[9] == 0x46) // F { return "image/jpeg"; } if(buf[0] == 0x89 && buf[1] == 0x50 // P && buf[2] == 0x4E // N && buf[3] == 0x47 // G && buf[4] == 0x0D // \r && buf[5] == 0x0A) // \n { return "image/png"; } if(buf[0] == 0x47 // G && buf[1] == 0x49 // I && buf[2] == 0x46 // F && buf[3] == 0x38 // 8 && buf[4] == 0x39 // 9 && buf[5] == 0x61) // a { return "image/gif"; } // unknown return ""; }, _droppedImageAssign: function(e){ var img,id; img = new Image(); img.src = e.target.result; ++this._uniqueId; id="snap-editor-image-"+this._uniqueId; jQuery(img).hide().attr("id",id).appendTo(e.target.snapEditorElement); jQuery("#"+id).show(); }, _droppedImage: function(e){ var mime, r, a, blob; mime = snapwebsites.EditorInstance._buffer2mime(e.target.result); if(mime.substr(0, 6) == "image/") { r = new FileReader; r.snapEditorElement = e.target.snapEditorElement; r.onload = snapwebsites.EditorInstance._droppedImageAssign; a = []; a.push(e.target.snapEditorFile); blob = new Blob(a, {type: mime}); // <- FORCE THE REAL MIME TYPE r.readAsDataURL(blob); } }, jQuery("#some-object") .on("drop",function(e){ // always prevent the default dropping mechanism // we handle the file manually all the way e.preventDefault(); e.stopPropagation(); // anything transferred on widget that accepts files? if(e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.files.length) { accept_images = jQuery(this).hasClass("image"); accept_files = jQuery(this).hasClass("attachment"); if(accept_images || accept_files) { for(i = 0; i < e.originalEvent.dataTransfer.files.length; ++i) { // read the image so we can make sure it is indeed an // image and ignore any other type of files r = new FileReader; r.snapEditorElement = this; r.snapEditorFile = e.originalEvent.dataTransfer.files[i]; r.onload = snapwebsites.EditorInstance._droppedImage; // Get the first 64 bytes of the file to check the magic code r.readAsArrayBuffer(r.snapEditorFile.slice(0, 64)); } } } return false; }) 
+6
source

I don't think you can rely on a browser to give you a MIME type. It would be much easier if you checked the file name extension. :)

If you really want to check the file type, read the payload using DataTransfer.getData() and check the leading bytes ( PNG , GIF89 , JFIF or something else).

+1
source

All Articles