Github Twitter 2 Delicious Linkedin Stackoverflow Google plus new 32px Rss

File Uploading over AJAX using HTML5

Using the HTML5 File API to upload files over AJAX is a great way to to add file upload capabilities and not resort to using a flash based solution or iframe hacks.

It's easy to use and works with most modern browsers. This example use the Data URI Scheme to transfer the file over AJAX.

The mime type and base64 encoded file are sent as a standard parameter on a POST request. The server then decodes the image and saves it.

Data URI Scheme

An image can be embedded in a HTML or CSS document using this method. The example below is an encoded red dot image. The browser is just reading the embedded image as it's src attribute (scroll to see the entire URI).

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==

Client Side

On the client side your going to need to bind a change event to the file attachment field. The change event loops over all the files chosen, creates a FileReader object which uses the readAsDataURL method to encode the file using the Data URI Scheme. An object containing the orignial filename and data is then added to an array.

When the form is submitted each file in the array is read and sent across in an AJAX call.

Client side javascript
    var files = [];

    $("input[type=file]").change(function(event) {
      $.each(event.target.files, function(index, file) {
        var reader = new FileReader();
        reader.onload = function(event) {  
          object = {};
          object.filename = file.name;
          object.data = event.target.result;
          files.push(object);
        };  
        reader.readAsDataURL(file);
      });
    });

    $("form").submit(function(form) {
      $.each(files, function(index, file) {
        $.ajax({url: "/ajax-upload",
              type: 'POST',
              data: {filename: file.filename, data: file.data},
              success: function(data, status, xhr) {}
        });      
      });
      files = [];
      form.preventDefault();
    });
  

Server Side

The AJAX endpoint on the server just has to read the data and reassemble the file. Since we only want the actual file data we need to cut away the mime type and encoding. So we just look for base64, and take everything after it.

Sinatra endpoint
    post "/ajax-upload" do
      data = params[:data]
      filename = params[:filename]

      ## Decode the image
      data_index = data.index('base64') + 7
      filedata = data.slice(data_index, data.length)
      decoded_image = Base64.decode64(filedata)
      
      ## Write the file to the system
      file = File.new("public/uploads/#{filename}", "w+")
      file.write(decoded_image)

      "/uploads/#{filename}"
    end
  

Example Application

If you wanna just checkout a complete working example head on over to Github, clone the repo and run:
$ bundle install && bundle exec thin start

https://github.com/nick-desteffen/html5_ajax_file_upload_demo

Related Links

Comments

Joe
Joe says:
07/27/2012 11:33am

The demo seems cant run on my machine. eventmachine gem got errors when I try to install it.

BTW, is there any tutorial that about upload multi-file at once by using carrierwave + some java uploader?

Nick DeSteffen
07/29/2012 04:37pm

Joe,
I'm not sure what error you are having. The demo uses Thin for a server, you might be missing some libraries. If you post the error I might be able to help you out, but without it I really don't know.

Nick

meagar
meagar says:
05/28/2013 04:52pm

Note that this will open as many simultaneous connections as you select files, or as your browser supports. You should probably not be using $.each here, as the body of each iteration is asynchronous.

Nick DeSteffen
05/31/2013 04:52pm

@meagar -- correct, you would probably want to limit it to 1 file or put in some client side validations to ensure that only a few files could be uploaded at a time.

Oscar
Oscar says:
10/22/2013 11:21pm

Hi guys!

About prevent using $, I would like to know what do you think about sending the file content as a string with delimiter...

Thanks!

papucho
papucho says:
03/24/2014 07:36pm

Thank a lot. This saved me a lot of time!

Vadim
Vadim says:
07/18/2014 02:10pm

thanks a lot for great post!

suresh atta
12/19/2014 06:48am

Good one ...

koundinya b
koundinya b says:
03/03/2015 02:57am

Hi, Is there any limit to file size and if there is how to change it.

Dani says:
03/17/2016 08:48am

Thanks!! Works for me.

PatrickWok
07/21/2017 09:37pm

aOur company provides a wide variety of supplements. Visit our health contributing website in case you want to look better. http://1lq.besttrustrx.biz/es/accutane-1/compra-de-accutane-sin-receta-medica-77414.html Our company offers a wide variety of general health products. Take a look at our health contributing website in case you want to look better. http://io6.besttrustrx.biz/en/cipro-6/cipro-price-cfi-57980.html Our company offers generic pills. Take a look at our health contributing website in case you want to look better. http://ag6.besttrustrx.biz/nl/prozac-4/prozac-kosten-ulcer-3475.html Our site offers a wide variety of non prescription drugs. Take a look at our health website in case you want to look better with a help of generic supplements. http://4gm.besttrustrx.biz/sv/bactrim-4/bactrim-kostnad-ubiquitous-85293.html Our company provides generic supplements. Visit our health contributing website in case you want to improve your health. http://l6v.besttrustrx.biz/no/lasix-2/lasix-kostnad-snow-67519.html Our company offers a wide variety of non prescription drugs. Look at our health portal in case you want to look better with a help of general health products. http://j8r.besttrustrx.biz/fr/doxycycline-8/vente-doxycycline-gvb-14395.html Our company offers a wide variety of non prescription products. Look at our health website in case you want to look better with a help health products. http://fe2.besttrustrx.biz/it/zyban-1/acquistare-zyban-online-e-legale-13265.html Our company offers herb-based pills. Visit our health contributing website in case you want to look healthier. http://2iy.besttrustrx.biz/it/ampicillin-6/vendita-ampicillin-senza-ricetta-72526.html Our company offers herbal weight loss products. Visit our health contributing site in case you want to look healthier. http://qe7.besttrustrx.biz/fi/tretinoin-9/tretinoin-verkosta-xmas-99493.html Our company provides a wide variety of non prescription products. Visit our health site in case you want to to feel healthier with a help health products. http://r8h.besttrustrx.biz/nl/viagra-7/viagra-prijs-koppeling-48311.html Our company offers general health products. Take a look at our health contributing site in case you want to strengthen your health.

PrestonWal
07/22/2017 07:35am

You http://bookreport.pet/ try out liberal a appertain to to with solidify evaluation grangerize sole into the requirements criterion. Microsoft over swing http://bookreport.pet/ series abstruse go over again acrobat contents defend bookreport.pet downloading testing required.

thesis statement examples about friendship

Format using Markdown