0

When dragging, dropping, or selecting a file through a form, IE 9/10/11 only accept JPEG and PNG files, but reject extensions JPG and GIF. Both the code I use below and the demo URL https://css-tricks.com/examples/DragAvatar/ have this problem. When dropping a JPG or GIF file on the demo, IE throws up a message box titled "Message from webpage", that reports "Only images are allowed!"

Renaming GIFs doesn't help, while renaming JPG to JPEG does work, but is a work-around I would not want to ask the user to perform. Is this a bug? Is it possible to rename the extension when the drag event fires? What can be done to support GIFs? Chrome and FF have no issues.

reader = new FileReader();
reader.onload = (function (theFile) {
    return function (event) {
        theHTML = '<img style="width: 100%;" src="' + event.target.result + '" />';
        document.getElementById('dropTarget').innerHTML = theHTML;
    };}(file));

reader.readAsDataURL(file);
Guessed
  • 417
  • 1
  • 4
  • 15
  • Not a bug. Your link to css-tricks works fine for me in IE11 if I drag a `.jpg` onto the avatar dropzone. I can even drop a .gif and the first image of the sequence will become the avatar (an animated gif is not supported by canvas). In your app, what file.type is being reported on the failed attempts? – markE May 11 '15 at 16:07
  • @markE I get a blank file.type. At this point I have switched to examining the file header, to remove all doubt. See how by Drakes at http://stackoverflow.com/questions/18299806/how-to-check-file-mime-type-with-javascript-before-upload – Guessed May 11 '15 at 16:57

3 Answers3

0

I think the solution for your problem is to use html5 drag and drop.

http://www.w3schools.com/Html/html5_draganddrop.asp

supported by IE9 and all other modern browsers..

Alon
  • 2,919
  • 6
  • 27
  • 47
0

Something's wrong with your image(s) if you're getting an undefined file.type when you should be getting some sort of image.* file type.

Here's a working demo that allows you to drag an image to a dropzone and create from it both an image an a new canvas drawing:

// dropDiv event handlers
var dropDiv=document.getElementById("dropDiv");
dropDiv.addEventListener("dragenter", handleDragEnter, false);
dropDiv.addEventListener("dragover", handleDragOver, false);
dropDiv.addEventListener("drop", handleDrop, false);
//
function handleDragEnter(e) {
  e.stopPropagation();
  e.preventDefault();
}
//
function handleDragOver(e) {
  e.stopPropagation();
  e.preventDefault();
}
//
function handleDrop(e) {
  e.stopPropagation();
  e.preventDefault();

  var dt = e.dataTransfer;
  var files = dt.files;

  handleFiles(files);
}

//
function handleFiles(files) {

  for (var i=0;i<files.length;i++) {
    var file = files[i];
    var imageType = /image.*/;

    if (!file.type.match(imageType)) {
      continue;
    }

    var img = document.createElement("img");
    img.classList.add("obj");
    img.file = file;
    preview.appendChild(img);

    var reader=new FileReader();
    reader.onload=(function(aImg){
      return function(e) {
        aImg.onload=function(){
          var canvas=document.createElement("canvas");
          var ctx=canvas.getContext("2d");
          canvas.width=aImg.width;
          canvas.height=aImg.height;
          ctx.drawImage(aImg,0,0);
          document.body.appendChild(canvas);
        }
        // e.target.result is a dataURL for the image
        aImg.src = e.target.result;
      }; 
    })(img);
    reader.readAsDataURL(file);

  } // end for

} // end handleFiles

function calcNewAspect(imgWidth, imgHeight, maxWidth, maxHeight) {
  var ratio = Math.min(maxWidth/imgWidth,maxHeight/imgHeight);
  return {width:imgWidth*ratio,height:imgHeight*ratio };
}
body{ background-color: ivory; }
canvas{border:1px solid red;}
#dropDiv{border:1px solid blue; width:300px;height:300px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Drag an image from desktop to blue dropzone.</h4>
<div id="dropDiv"></div>
<div id="preview"></div>
markE
  • 102,905
  • 11
  • 164
  • 176
  • Thanks @markE. I ran the code snippet on 4 different machines and it failed with IE 9 on Vista, IE 9 on Windows Server 2003, and IE 11 on Windows 7. Only IE 11 on Windows Server 2012 worked. I'll have to stick with reading the magic number to positively fingerprint the MIME and not rely on blob.type test compatibility. The problem is not the file. The problem is the test. – Guessed May 11 '15 at 18:30
  • Yep, IE9 does not support FileReader (as used in my snippet). IE10 supports FileReader and I can successfully drag a jpg on IE10+ on Win8. Also, when you say "selecting a file through a form" does that mean you're using the download attribute? The download attribute is not available until IE12-Edge? PS. Kudos for testing your app on Windows Server(s)--not many clients will be coming from that platform but you are thorough! :-) – markE May 11 '15 at 19:37
  • Actually, @markE, there's no form, just a file type input element, for those who aren't into drag and drop. It's possible that having Windows Update disabled has prevented hotfixes to the OS's before Win8/Server2012. I didn't plan to drill down into header sniffing, but now appreciate the reliability of the approach, and mild hardening effect - not that a hacker can't re-write the header. That's ok, though, since I don't upload the source, but a cropped copy off the canvas. – Guessed May 11 '15 at 20:21
0

The problem lies neither in the FileReader code used nor in the file selected. The bug is induced by testing file.type.match('image.*') in IE 9/10/11 running on Windows Vista or 7. JPG and GIF files are reported as type blank to JavaScript. To handle this, ignore the file's extension and directly read the header of the file to determine its MIME.

To read a file header, see the answer by Drakes at How to check file MIME type with javascript before upload?

Community
  • 1
  • 1
Guessed
  • 417
  • 1
  • 4
  • 15