Get binary image data from input type "file" using JavaScript/jQuery for use with picture preview with AJAX in WebMatrix

VoidKing picture VoidKing · Nov 1, 2012 · Viewed 11.4k times · Source

I have had trouble when researching or otherwise trying to figure out how (if it's even possible) to get binary image data using JavaScript/jQuery from an html input element of type file.

I'm using WebMatrix (C#), but it may not be necessary to know that, if the purposes of this question can be answered using JavaScript/jQuery alone.

I can take the image, save it in the database (as binary data), then later show the pic on the page, from the binary data, after posting. This does, however, leave me without a pic preview, before uploading, for which I am almost certain I must use AJAX.

Again, this may not even be possible, but as long as I can get the binary image data, I believe I can push it to the server with AJAX and process the image the same way I would if I were taking it from a database (note that I don't save the image files themselves using GUID and all that,I just save the binary data).

If there is an easier way to show a pic preview using the input element, that would work fine, too, of course, as the whole idea behind me trying to do this is to show a pic preview before they hit the submit form button (or at least create that illusion).

**********UPDATE***********

I do not consider this a duplicate of another question because, my real question is:

How can I get image data from an input type "file", with JavaScript/jQuery?

If I can just get the data (in the right format) back to the server, I should be able to work with it there, and then return it with AJAX (although, I am absolutely no AJAX expert).

There is, according to the research that I have done, NO WAY to get picture previews in all IE versions using only javascript (this is because getting the full file path is seen, by them, as a potential security risk). I could ask my users to add the site to the trusted sites, but you don't usually ask users to tamper with those kinds of settings (not to mention the quickest way to make your site seem suspicious to users is to ask them to directly add your site to the trusted sites list. That's like sending an email and asking for a password. "Just trust me! I'm soooo safe!" :)

Answer

Vicary picture Vicary · Nov 1, 2012

Short answer: Use the jQuery form plugin, it suports AJAX-like form submits even for file uploads.

tl;dr

Thumbnail preview is popular websites is usually done by a number of steps, basically the website do these steps:

  1. upload the RAW image
  2. Resize and optimise the image for data storage
  3. Generate a temporary link to that file (usually stored in a server maintained HTTP session)
  4. Send it back to the user, to enable a 'preview'
  5. Actually store the image after user confirms the image

A few bad solutions are:

  1. Most of the modern browsers has options to enable script access to local files, but usually you don't ask your users to tinker with those low level settings.
  2. Earlier Internet Explorer (ah... yes it's a shame) and ancient versions of modern browsers will expose the full file path by reading the 'value' of file input box, which you can directly generates an tag and use that value. (Now it is replaced by some c:/fakepath/... thing.)
  3. Use Adobe Flash to mimic the file selection panel, it can properly read local files. But passing it into JavaScript is another topic...

Hope these helps. ;)

UPDATE

I actually came across a situation that requires a preview before uploading, I'd like to also put it here. As I could recall, there were no transitional versions in modern browsers that do not implement FileReader before masking the real file path, but feel free to correct me if so. This solution should caters most of the browsers, as long as they are supported by jQuery.

// 1. Listen to change event
$(':file').change(function() {
  // 2. Check if it has the FileReader class
  if (!this.files) {
    // 2.1. Old enough to assume a real path
    setPreview(this.value);
  }
  else {
    // 2.2. Read the file content.
    var reader = new FileReader();

    reader.onload = function() {
      setPreview(reader.result);
    };

    reader.readAsDataURL();
  }
});

function setPreview(url) {
  // Do preview things.
  $('.preview').attr('src', url);
}