By Sergio del Amo


2008-10-03 10:22:17 8 Comments

I would like to upload a file asynchronously with jQuery. This is my HTML:

<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>

And here my Jquery code:

$(document).ready(function () {
    $("#uploadbutton").click(function () {
        var filename = $("#file").val();

        $.ajax({
            type: "POST",
            url: "addFile.do",
            enctype: 'multipart/form-data',
            data: {
                file: filename
            },
            success: function () {
                alert("Data Uploaded: ");
            }
        });
    });
});

Instead of the file being uploaded, I am only getting the filename. What can I do to fix this problem?

Current Solution

I am using the jQuery Form Plugin to upload files.

28 comments

@404 2014-08-25 14:17:29

Wrapping up for future readers.

Asynchronous File Upload

With HTML5

You can upload files with jQuery using the $.ajax() method if FormData and the File API are supported (both HTML5 features).

You can also send files without FormData but either way the File API must be present to process files in such a way that they can be sent with XMLHttpRequest (Ajax).

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  data: new FormData($('#formWithFiles')[0]), // The form with the file inputs.
  processData: false,
  contentType: false                    // Using FormData, no need to process data.
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

For a quick, pure JavaScript (no jQuery) example see "Sending files using a FormData object".

Fallback

When HTML5 isn't supported (no File API) the only other pure JavaScript solution (no Flash or any other browser plugin) is the hidden iframe technique, which allows to emulate an asynchronous request without using the XMLHttpRequest object.

It consists of setting an iframe as the target of the form with the file inputs. When the user submits a request is made and the files are uploaded but the response is displayed inside the iframe instead of re-rendering the main page. Hiding the iframe makes the whole process transparent to the user and emulates an asynchronous request.

If done properly it should work virtually on any browser, but it has some caveats as how to obtain the response from the iframe.

In this case you may prefer to use a wrapper plugin like Bifröst which uses the iframe technique but also provides a jQuery Ajax transport allowing to send files with just the $.ajax() method like this:

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  // Set the transport to use (iframe means to use Bifröst)
  // and the expected data type (json in this case).
  dataType: 'iframe json',                                
  fileInputs: $('input[type="file"]'),  // The file inputs containing the files to send.
  data: { msg: 'Some extra data you might need.'}
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

Plugins

Bifröst is just a small wrapper that adds fallback support to jQuery's ajax method, but many of the aforementioned plugins like jQuery Form Plugin or jQuery File Upload include the whole stack from HTML5 to different fallbacks and some useful features to ease out the process. Depending on your needs and requirements you might want to consider a bare implementation or either of this plugins.

@ash 2015-08-18 22:44:55

One thing to note, based on the documentation: you should also send contentType: false. When I didn't send this with chrome the form content type was invalidated by jQuery.

@Zero3 2015-12-19 18:10:32

Nice answer. A few suggestions for improvement: Remove the parts of the code unrelated to the answer, for example the .done() and .fail() callbacks. Also, an example without the use of FormData and a list of pro/cons would be awesome.

@candlejack 2016-12-25 23:15:44

I got this error: TypeError: Argument 1 of FormData.constructor does not implement interface HTMLFormElement.

@Mattias 2008-10-03 10:36:38

Note: This answer is outdated, it is now possible to upload files using XHR.


You cannot upload files using XMLHttpRequest (Ajax). You can simulate the effect using an iframe or Flash. The excellent jQuery Form Plugin that posts your files through an iframe to get the effect.

@Mattias 2008-10-03 17:21:49

Yes, you can POST to an iframe and capture the file there. I have very limited experience with this though, so I can't really comment on it.

@Alleo 2011-11-03 18:57:48

Small remark: in latest versions of chrome and firefox it is possible, stackoverflow.com/questions/4856917/…

@ArtisticPhoenix 2014-06-26 04:43:12

The simplest and most robust way I have done this in the past, is to simply target a hidden iFrame tag with your form - then it will submit within the iframe without reloading the page.

That is if you don't want to use a plugin, JavaScript or any other forms of "magic" other than HTML. Of course you can combine this with JavaScript or what have you...

<form target="iframe" action="" method="post" enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>

<iframe name="iframe" id="iframe" style="display:none" ></iframe>

You can also read the contents of the iframe onLoad for server errors or success responses and then output that to user.

Chrome, iFrames, and onLoad

-note- you only need to keep reading if you are interested in how to setup a UI blocker when doing uploading/downloading

Currently Chrome doesn't trigger the onLoad event for the iframe when it's used to transfer files. Firefox, IE, and Edge all fire the onload event for file transfers.

The only solution that I found works for Chrome was to use a cookie.

To do that basically when the upload/download is started:

  • [Client Side] Start an interval to look for the existence of a cookie
  • [Server Side] Do whatever you need to with the file data
  • [Server Side] Set cookie for client side interval
  • [Client Side] Interval sees the cookie and uses it like the onLoad event. For example you can start a UI blocker and then onLoad ( or when cookie is made ) you remove the UI blocker.

Using a cookie for this is ugly but it works.

I made a jQuery plugin to handle this issue for Chrome when downloading, you can find here

https://github.com/ArtisticPhoenix/jQuery-Plugins/blob/master/iDownloader.js

The same basic principal applies to uploading, as well.

To use the downloader ( include the JS, obviously )

 $('body').iDownloader({
     "onComplete" : function(){
          $('#uiBlocker').css('display', 'none'); //hide ui blocker on complete
     }
 });

 $('somebuttion').click( function(){
      $('#uiBlocker').css('display', 'block'); //block the UI
      $('body').iDownloader('download', 'htttp://example.com/location/of/download');
 });

And on the server side, just before transferring the file data, create the cookie

 setcookie('iDownloader', true, time() + 30, "/");

The plugin will see the cookie, and then trigger the onComplete callback.

@Yevgeniy Afanasyev 2015-01-05 22:45:43

I love it. If only someone could mention the potential problems with this brilliant solution. I really don't understand why people wright and use these clunky libraries and plugins when there is the solution.

@Prakhar Mishra 2016-06-28 11:19:33

Well, I guess the reason would be to show some progress info while uploading.

@noobs 2018-05-21 10:14:35

You can use newer Fetch API by JavaScript. Like this:

function uploadButtonCLicked(){
    var input = document.querySelector('input[type="file"]')

    fetch('/url', {
      method: 'POST',
      body: input.files[0]
    }).then(res => res.json())   // you can do something with response
      .catch(error => console.error('Error:', error))
      .then(response => console.log('Success:', response));
}                               

Advantage: Fetch API is natively supported by all modern browsers, so you don't have to import anything. Also, note that fetch() returns a Promise which is then handled by using .then(..code to handle response..) asynchronously.

@Erick Langford Xenes 2015-11-03 20:47:25

This is my solution.

<form enctype="multipart/form-data">    

    <div class="form-group">
        <label class="control-label col-md-2" for="apta_Description">Description</label>
        <div class="col-md-10">
            <input class="form-control text-box single-line" id="apta_Description" name="apta_Description" type="text" value="">
        </div>
    </div>

    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>

and the js

<script>

    $(':button').click(function () {
        var formData = new FormData($('form')[0]);
        $.ajax({
            url: '@Url.Action("Save", "Home")',  
            type: 'POST',                
            success: completeHandler,
            data: formData,
            cache: false,
            contentType: false,
            processData: false
        });
    });    

    function completeHandler() {
        alert(":)");
    }    
</script>

Controller

[HttpPost]
public ActionResult Save(string apta_Description, HttpPostedFileBase file)
{
    return Json(":)");
}

@Zero3 2015-12-19 18:06:46

You seem to have mixed some kind of framework into your answer. You should, at the very least, mention which framework your answer is usable for. Better yet, remove all the framework stuff and present only an answer to the question posed.

@nonchip 2016-01-06 22:27:47

so there's actually a mvc framework called "mvc"? and it uses csharpish syntax? that's cruel.

@olanod 2012-01-06 13:34:48

With HTML5 you can make file uploads with Ajax and jQuery. Not only that, you can do file validations (name, size, and MIME type) or handle the progress event with the HTML5 progress tag (or a div). Recently I had to make a file uploader, but I didn't want to use Flash nor Iframes or plugins and after some research I came up with the solution.

The HTML:

<form enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>
<progress></progress>

First, you can do some validation if you want. For example, in the onChange event of the file:

$(':file').on('change', function() {
    var file = this.files[0];
    if (file.size > 1024) {
        alert('max upload size is 1k')
    }

    // Also see .name, .type
});

Now the Ajax submit with the button's click:

$(':button').on('click', function() {
    $.ajax({
        // Your server script to process the upload
        url: 'upload.php',
        type: 'POST',

        // Form data
        data: new FormData($('form')[0]),

        // Tell jQuery not to process data or worry about content-type
        // You *must* include these options!
        cache: false,
        contentType: false,
        processData: false,

        // Custom XMLHttpRequest
        xhr: function() {
            var myXhr = $.ajaxSettings.xhr();
            if (myXhr.upload) {
                // For handling the progress of the upload
                myXhr.upload.addEventListener('progress', function(e) {
                    if (e.lengthComputable) {
                        $('progress').attr({
                            value: e.loaded,
                            max: e.total,
                        });
                    }
                } , false);
            }
            return myXhr;
        }
    });
});

As you can see, with HTML5 (and some research) file uploading not only becomes possible but super easy. Try it with Google Chrome as some of the HTML5 components of the examples aren't available in every browser.

@Dan 2012-05-10 03:21:41

How do return data from the file that the file was posted to?

@olanod 2012-05-13 19:49:32

@Silver89 if you mean to return data from the server script you set in the url setting('upload.php' in this case), the response will be whatever you print or echo in that script. Then you can do whatever you want with the data. Check the ajaxComplete and similar functions in jQuery Docs

@Dan 2012-06-05 04:26:24

I have the file part working ... but can you include text fields in this as well? This doesn't seem to with var formData = new FormData($('form')[0]); or serialize() ?

@olanod 2012-06-05 10:57:03

with "new FormData($('form')[0]);" it should work, your text field has a name? use print_r on $_POST to make sure data is there, check the response on the network monitor(chrome) to see the raw response.

@Alessandro Cosentino 2012-11-02 13:41:48

Can I then use $_FILES in the upload.php?

@Samir 2013-01-02 16:33:44

This should work in Internet Explorer but only Version 10. (caniuse.com/xhr2)

@KevinDeus 2013-05-06 21:39:56

Doesn't work in IE7-9

@Zugwalt 2013-05-09 16:24:52

Awesome answer! Minor edit: should have var keyword to scope myXhr variable in third code snippet.

@Shumii 2013-06-01 05:29:32

Hi, I appreciate PHP is your language of choice... but I am wondering if you know if this also works in ASP.NET MVC? I am a .NET developer and I have tried to utilize your simple example to do some AJAX file uploading but server side I do not get the file I posted via AJAX. I am using latest Chrome.

@indapublic 2013-06-10 14:32:46

Can i use upload in $('input:file').change()? I'm trying, but I have zero-sized $_FILES and $_POST in php script

@RyanDawkins 2013-07-16 15:44:33

@olanod is it possible to upload more data with this?

@incarnate 2013-09-12 13:26:28

It's FormData who does all the magic here. Be sure to check these docs — it covers all your question about multiple files and fields.

@Alex Barker 2014-01-08 00:40:58

This doesn't appear to work with jquery. I cannot pass a FormData object to .ajax() as the data setting is either type PlainObject or String. I have to be missing something if this broken example got 775 votes.

@think123 2014-01-26 03:03:18

do you need to write contentType: false?

@Rahly 2014-02-19 21:20:49

Although I love this, I still feel its not complete. I designed our AJAX to upload the file in chunks, and although it tends to upload load a bit more than, its a lot more robust, and also allows the user to "pause" and "resume/retry" uploads.

@Code_Crash 2014-03-29 05:49:38

first of all thank's to share it.. but please can any one tell me how to handle this file in 'upload.php' to process it.

@Code_Crash 2014-03-29 06:12:53

@olanod Hello sir. thanks for this . please can you tell me how to handle this file in upload.php

@LosManos 2014-04-20 21:10:30

For those interested: In Aspnetmvc the server code is as simple as public ActionResult Upload() { var files = Request.Files ...

@hakan 2014-05-13 16:54:16

I am using .net and copy pasted js. I dont see anything posted either Request.Files or Request.Form. What should I do?

@JavaTechnical 2014-10-07 15:48:16

How to handle <input name="file" type="file" multiple="multiple"/> here? Thank you.

@Cesar Bielich 2014-10-13 22:44:22

I know its been a while since a comment on this but I am using this example and for some reason my php file is returning a black array when I use print_r($_POST)

@Mohit Kumar Gupta 2014-12-08 12:48:45

How to send Post request with FormData() in IE 10.0.9200 ?

@Brownman Revival 2015-02-21 10:41:26

@olanod i asked a similar question can you check it and give an answer?stackoverflow.com/questions/28644200/…

@Hasan 2015-07-19 09:44:36

After XmlHttpRequest, $_FILES["file"]["name"] can't catch the file in server side. What do you suggest me?

@Gone Coding 2015-08-10 08:56:19

Just a minor note: POST requests are never cached, so the cache: false option is redundant here.

@Deji 2015-09-22 10:16:43

Aside from the optional usage of the HTML5 <progress> tag, I don't see any reason HTML5 has so much attention in this answer when good ol' JS and PHP are doing the job themselves...

@Brett Caswell 2015-10-29 13:49:57

@Deji, the html5 control <input type="file"> is what is relevant here. the js event handling is provided as to make the uploading of that file (after the user interacts with the control) asynchronous. Infact, you wouldn't need js at all if you submitted the form, but, again, that wouldn't be asynchronous.

@Deji 2015-10-29 13:55:32

@BrettCaswell But again, that is nothing to do with HTML5. That has existed for donkey's years.

@Brett Caswell 2015-10-29 15:05:05

@Deji, ah I see.. it certainly has.. though the behavior seems it may have changed in html5 (vocabulary and associated APIs for HTML and XHTML)[w3.org/TR/html5/forms.html#file-upload-state-(type=fi‌​le)]

@Brett Caswell 2015-10-29 15:11:37

@Deji, hmm, actually.. the doc lists HtmlInputElment [type='file'] was extended, not changed (which makes sense, since we're talking about interfaces here).. w3.org/TR/html5-diff/#other-extensions.. so I guess this answer is applicable to XHTML, and not solely HTML5 (though, the raising of the onchange event may be new in the implementation)

@Kivak Wolf 2015-12-30 20:30:06

Just so someone else doesn't spend hours... the name="file" is very important on the <input> file tag if you're going to use the data in PHP (and probably other places). I created a form dynamically using javascript so I didn't need the name attribute but found out the hard way you absolutely need it to retrieve the data server-side.

@Joseph 2016-01-21 10:37:19

Hi @olanod, I have a similar problem, I am not able to pass a file by ajax so that it can be used in Symfony2. can you help me? You can see my question here

@Thomas Williams 2016-07-27 23:15:20

Can you tell me where you call the progress function. I have written a full html5 plugin which does my upload, but not sure how to implement the progress.

@olanod 2016-07-29 08:31:10

In the block where the xhr object is edited, an event listener for the progress event is added to the xhr.upload object. If you want to do something on progress just apply your logic in the callback passed to that event listener(progressHandlingFunction).

@Davinder Kumar 2017-01-10 12:41:02

Post sending empty when i upload file more than 250 MB

@Gowthaman 2017-03-31 15:33:52

its not working

@Alireza 2018-03-12 12:32:13

Using HTML5 and JavaScript, uploading async is quite easy, I create the uploading logic along with your html, this is not fully working as it needs the api, but demonstrate how it works, if you have the endpoint called /upload from root of you website, this code should works for you:

const asyncFileUpload = () => {
  const fileInput = document.getElementById("file");
  const file = fileInput.files[0];
  const uri = "/upload";
  const xhr = new XMLHttpRequest();
  xhr.upload.onprogress = e => {
    const percentage = e.loaded / e.total;
    console.log(percentage);
  };
  xhr.onreadystatechange = e => {
    if (xhr.readyState === 4 && xhr.status === 200) {
      console.log("file uploaded");
    }
  };
  xhr.open("POST", uri, true);
  xhr.setRequestHeader("X-FileName", file.name);
  xhr.send(file);
}
<form>
  <span>File</span>
  <input type="file" id="file" name="file" size="10" />
  <input onclick="asyncFileUpload()" id="upload" type="button" value="Upload" />
</form>

Also some further information about XMLHttpReques:

The XMLHttpRequest Object

All modern browsers support the XMLHttpRequest object. The XMLHttpRequest object can be used to exchange data with a web server behind the scenes. This means that it is possible to update parts of a web page, without reloading the whole page.


Create an XMLHttpRequest Object

All modern browsers (Chrome, Firefox, IE7+, Edge, Safari, Opera) have a built-in XMLHttpRequest object.

Syntax for creating an XMLHttpRequest object:

variable = new XMLHttpRequest();


Access Across Domains

For security reasons, modern browsers do not allow access across domains.

This means that both the web page and the XML file it tries to load, must be located on the same server.

The examples on W3Schools all open XML files located on the W3Schools domain.

If you want to use the example above on one of your own web pages, the XML files you load must be located on your own server.

For more details, you can continue reading here...

@LAT94 2018-02-21 14:41:37

It is an old question, but still has no answer correct answer, so:

Have you tried jQuery-File-Upload ?

Here is an example from the link above -> 1 that might solve your problem:

$('#fileupload').fileupload({
    add: function (e, data) {
        var that = this;
        $.getJSON('/example/url', function (result) {
            data.formData = result; // e.g. {id: 123}
            $.blueimp.fileupload.prototype
                .options.add.call(that, e, data);
        });
    } 
});

@Allende 2015-07-08 17:59:34

Look for Handling the upload process for a file, asynchronously in here: https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications

Sample from the link

<?php
if (isset($_FILES['myFile'])) {
    // Example:
    move_uploaded_file($_FILES['myFile']['tmp_name'], "uploads/" . $_FILES['myFile']['name']);
    exit;
}
?><!DOCTYPE html>
<html>
<head>
    <title>dnd binary upload</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script type="text/javascript">
        function sendFile(file) {
            var uri = "/index.php";
            var xhr = new XMLHttpRequest();
            var fd = new FormData();

            xhr.open("POST", uri, true);
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    // Handle response.
                    alert(xhr.responseText); // handle response.
                }
            };
            fd.append('myFile', file);
            // Initiate a multipart/form-data upload
            xhr.send(fd);
        }

        window.onload = function() {
            var dropzone = document.getElementById("dropzone");
            dropzone.ondragover = dropzone.ondragenter = function(event) {
                event.stopPropagation();
                event.preventDefault();
            }

            dropzone.ondrop = function(event) {
                event.stopPropagation();
                event.preventDefault();

                var filesArray = event.dataTransfer.files;
                for (var i=0; i<filesArray.length; i++) {
                    sendFile(filesArray[i]);
                }
            }
        }
    </script>
</head>
<body>
    <div>
        <div id="dropzone" style="margin:30px; width:500px; height:300px; border:1px dotted grey;">Drag & drop your file here...</div>
    </div>
</body>
</html>

@Zayn Ali 2014-08-08 02:59:30

You can upload simply with jQuery .ajax().

HTML:

<form id="upload-form">
    <div>
        <label for="file">File:</label>
        <input type="file" id="file" name="file" />
        <progress class="progress" value="0" max="100"></progress>
    </div>
    <hr />
    <input type="submit" value="Submit" />
</form>

CSS

.progress { display: none; }

Javascript:

$(document).ready(function(ev) {
    $("#upload-form").on('submit', (function(ev) {
        ev.preventDefault();
        $.ajax({
            xhr: function() {
                var progress = $('.progress'),
                    xhr = $.ajaxSettings.xhr();

                progress.show();

                xhr.upload.onprogress = function(ev) {
                    if (ev.lengthComputable) {
                        var percentComplete = parseInt((ev.loaded / ev.total) * 100);
                        progress.val(percentComplete);
                        if (percentComplete === 100) {
                            progress.hide().val(0);
                        }
                    }
                };

                return xhr;
            },
            url: 'upload.php',
            type: 'POST',
            data: new FormData(this),
            contentType: false,
            cache: false,
            processData: false,
            success: function(data, status, xhr) {
                // ...
            },
            error: function(xhr, status, error) {
                // ...
            }
       });
    }));
});

@Tarek Kalaji 2015-02-16 14:28:21

thank you it is work on .xls upload files

@Rayden Black 2015-12-16 02:32:10

What jQuery library do I need t o run this code?

@Zayn Ali 2015-12-18 00:34:06

@RaydenBlack only jQuery.

@Ali Sherafat 2017-07-22 18:24:14

how to get upload progress?

@Zayn Ali 2017-07-23 00:53:49

@AliSherafat i've updated my answer. try it

@pixxaar 2008-11-21 16:38:06

I recommend using the Fine Uploader plugin for this purpose. Your JavaScript code would be:

$(document).ready(function() {
  $("#uploadbutton").jsupload({
    action: "addFile.do",
    onComplete: function(response){
      alert( "server response: " + response);
    }
  });
});

@Lorenzo Manucci 2011-06-22 09:35:43

It uses JSON - so for PHP old version it will be non possible use.

@ripper234 2011-12-06 14:52:46

Seems much cleaner than Ajax File Upload, where I need to include a huge piece of code just to use the damn thing.

@Patrick Fisher 2012-02-12 02:07:08

@Simon East 2012-07-01 01:43:50

Newer URL for version 2 is now valums-file-uploader.github.com/file-uploader

@Trantor Liu 2012-07-23 12:02:24

"This plugin is open sourced under GNU GPL 2 or later and GNU LGPL 2 or later." So as long as you don't distribute the copy or a modified version, you don't have to open your project.

@James McCormack 2012-10-01 21:19:44

Am I missing something? This library doesn't seem to use jquery any more, so it doesn't support the syntax from the answer?

@Darren Cook 2013-11-28 02:08:27

@Kerry Do you have a link regarding MIT license? The latest version (Version 4) appears to be GPL3 only, no LGPL: github.com/Widen/fine-uploader#license Version 2 mentions LGPL: valums-file-uploader.github.io/file-uploader

@Kerry Jones 2013-11-28 14:16:03

@DarrenCook Yeah, I noticed that earlier this year. I have a downloaded copy of the old code, not as pretty, but it still has the old license, but not online.

@Andrew_1510 2014-02-05 10:25:40

This is the website (fineuploader.com) I found now, it's V4.2 .

@Ankan-Zerob 2014-05-27 20:44:35

@BryanLarsen You do not need to release the code if it is a website (or a SaaS solution), since you are not distributing the "binary", you do not need to distribute the code. Some resources : stackoverflow.com/questions/3701011/…

@Oli 2015-09-22 10:36:37

They have switched license again. it's a proprietary license that separately calls out commercial use, so unlike the GPL, there is no escape from licensing the latest version for commercial use. This is the last committed version available under GPL (Dec 2014).

@Ray Nicholus 2016-05-14 21:54:13

As of Fine Uploader 5.9.0, the library is now 100% Free Open Source Software and MIT licensed.

@Oli 2008-10-03 10:41:31

2017 Update: It still depends on the browsers your demographic uses.

An important thing to understand with the "new" HTML5 file API is that is wasn't supported until IE 10. If the specific market you're aiming at has a higher-than-average prepensity toward older versions of Windows, you might not have access to it.

Going into 2017, about 5% of browsers are one of IE 6, 7, 8 or 9. If you head into a big corporation (eg this is a B2B tool, or something you're delivering for training) that number can rocket. Just a few months ago —in 2016— I dealt with a company using IE8 on over 60% of their machines.

So before you do anything: check what browser your users use. If you don't, you'll learn a quick and painful lesson in why "works for me" isn't good enough in a deliverable to a client.

My answer from 2008 follows.


However, there are viable non-JS methods of file uploads. You can create an iframe on the page (that you hide with CSS) and then target your form to post to that iframe. The main page doesn't need to move.

It's a "real" post so it's not wholly interactive. If you need status you need something server-side to process that. This varies massively depending on your server. ASP.NET has nicer mechanisms. PHP plain fails, but you can use Perl or Apache modifications to get around it.

If you need multiple file-uploads, it's best to do each file one at a time (to overcome maximum file upload limits). Post the first form to the iframe, monitor its progress using the above and when it has finished, post the second form to the iframe, and so on.

Or use a Java/Flash solution. They're a lot more flexible in what they can do with their posts...

@meleyal 2011-03-25 10:05:26

For the record it's now possible to do pure AJAX file uploads if the browser supports the File API - developer.mozilla.org/en/using_files_from_web_applications

@Oli 2014-02-05 02:45:26

Unless you need IE9 support. caniuse.com/fileapi

@Matthew Lock 2015-04-17 00:45:09

iframe solution is pretty simple and easy to get working

@Brett Caswell 2015-10-29 14:54:52

this is quite an old answer, but it was a bit misleading.. IE supported XHR natively as far back as IE7, and supported it through ActiveX as far back as IE5. w3schools.com/ajax/ajax_xmlhttprequest_create.asp. The practical way of doing this was certainly targeting flash (shockwave) components, or rolling out a Flash/ActiveX (Silverlight) control. If you can originate a request and handle the response via javascript, it's ajax.. though, having said that, ajax is synonymous with xhr, but it doesn't itself describe the underline mechanism/components that delivers/exchanges the payload.

@Oli 2015-10-29 15:34:04

@BrettCaswell I wasn't saying that AJAX/XHR weren't possible, just that it wasn't possible to post a file up with them on old —but everliving— versions of IE. That was and remains completely true.

@MEAbid 2016-10-14 07:17:46

Sample: If you use jQuery, you can do easy to an upload file. This is a small and strong jQuery plugin, http://jquery.malsup.com/form/.

Example

var $bar   = $('.ProgressBar');
$('.Form').ajaxForm({
  dataType: 'json',

  beforeSend: function(xhr) {
    var percentVal = '0%';
    $bar.width(percentVal);
  },

  uploadProgress: function(event, position, total, percentComplete) {
    var percentVal = percentComplete + '%';
    $bar.width(percentVal)
  },

  success: function(response) {
    // Response
  }
});

I hope it would be helpful

@Daniel Nyamasyo 2016-07-19 05:18:34

You can see a solved solution with a working demo here that allows you to preview and submit form files to the server. For your case, you need to use Ajax to facilitate the file upload to the server:

<from action="" id="formContent" method="post" enctype="multipart/form-data">
    <span>File</span>
    <input type="file" id="file" name="file" size="10"/>
    <input id="uploadbutton" type="button" value="Upload"/>
</form>

The data being submitted is a formdata. On your jQuery, use a form submit function instead of a button click to submit the form file as shown below.

$(document).ready(function () {
   $("#formContent").submit(function(e){

     e.preventDefault();
     var formdata = new FormData(this);

 $.ajax({
     url: "ajax_upload_image.php",
     type: "POST",
     data: formdata,
     mimeTypes:"multipart/form-data",
     contentType: false,
     cache: false,
     processData: false,
     success: function(){

     alert("successfully submitted");

     });
   });
});

View more details

@Siddhartha Chowdhury 2016-03-30 16:48:31

Here's just another solution of how to upload file (without any plugin)

Using simple Javascripts and AJAX (with progress-bar)

HTML part

<form id="upload_form" enctype="multipart/form-data" method="post">
    <input type="file" name="file1" id="file1"><br>
    <input type="button" value="Upload File" onclick="uploadFile()">
    <progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
    <h3 id="status"></h3>
    <p id="loaded_n_total"></p>
</form>

JS part

function _(el){
    return document.getElementById(el);
}
function uploadFile(){
    var file = _("file1").files[0];
    // alert(file.name+" | "+file.size+" | "+file.type);
    var formdata = new FormData();
    formdata.append("file1", file);
    var ajax = new XMLHttpRequest();
    ajax.upload.addEventListener("progress", progressHandler, false);
    ajax.addEventListener("load", completeHandler, false);
    ajax.addEventListener("error", errorHandler, false);
    ajax.addEventListener("abort", abortHandler, false);
    ajax.open("POST", "file_upload_parser.php");
    ajax.send(formdata);
}
function progressHandler(event){
    _("loaded_n_total").innerHTML = "Uploaded "+event.loaded+" bytes of "+event.total;
    var percent = (event.loaded / event.total) * 100;
    _("progressBar").value = Math.round(percent);
    _("status").innerHTML = Math.round(percent)+"% uploaded... please wait";
}
function completeHandler(event){
    _("status").innerHTML = event.target.responseText;
    _("progressBar").value = 0;
}
function errorHandler(event){
    _("status").innerHTML = "Upload Failed";
}
function abortHandler(event){
    _("status").innerHTML = "Upload Aborted";
}

PHP part

<?php
$fileName = $_FILES["file1"]["name"]; // The file name
$fileTmpLoc = $_FILES["file1"]["tmp_name"]; // File in the PHP tmp folder
$fileType = $_FILES["file1"]["type"]; // The type of file it is
$fileSize = $_FILES["file1"]["size"]; // File size in bytes
$fileErrorMsg = $_FILES["file1"]["error"]; // 0 for false... and 1 for true
if (!$fileTmpLoc) { // if file not chosen
    echo "ERROR: Please browse for a file before clicking the upload button.";
    exit();
}
if(move_uploaded_file($fileTmpLoc, "test_uploads/$fileName")){ // assuming the directory name 'test_uploads'
    echo "$fileName upload is complete";
} else {
    echo "move_uploaded_file function failed";
}
?>

Here's the EXAMPLE application

@Zameer Fouzan 2018-01-31 14:16:26

Does not work with IE9.

@Vivek Aasaithambi 2015-07-28 13:39:10

var formData=new FormData();
formData.append("fieldname","value");
formData.append("image",$('[name="filename"]')[0].files[0]);

$.ajax({
    url:"page.php",
    data:formData,
    type: 'POST',
    dataType:"JSON",
    cache: false,
    contentType: false,
    processData: false,
    success:function(data){ }
});

You can use form data to post all your values including images.

@Gone Coding 2015-08-10 09:10:27

Note: cache: false is redundant on a POST request as POST never caches.

@candlejack 2016-12-25 23:28:42

@Vivek Aasaithambi, I got this error: TypeError: Argument 1 of FormData.constructor does not implement interface HTMLFormElement.

@Cheery 2008-10-15 10:35:59

There are various ready-made plugins on doing file upload for jQuery.

Doing this kind of uploading hacks is not an enjoyable experience, so people enjoy using ready-made solutions.

Here's few:

You can search for more projects on NPM (using "jquery-plugin" as the keyword) or on Github.

@UlfR 2009-07-16 06:31:18

The AjaxFUP-link seems to be broken. I suspect this is what is refered to: valums.com/ajax-upload

@brettcvz 2012-06-21 23:19:19

For yet another read-made plugin, there's always Filepicker.io, which is kind of nice in that it deals with all of the nasty large file support issues, etc.

@mpen 2013-02-17 09:30:51

It's actually only about 10 lines of vanilla JS. It really isn't so bad.

@fletchsod 2014-09-02 13:54:15

Ready-made solution plugins may work great but it doesn't help after a while you find out it doesn't work you thought it would and you had to hack it with unfamiliar scripts. So, it goes both ways.

@Mr world wide 2017-02-13 11:45:21

Can i use JQuery File Uploader for multiple videos..? will it support..?

@Hristo 2011-04-08 16:43:57

I've come across a few really powerful jQuery-based file upload libraries. Check these out:

  1. Plupload
  2. jQuery File Upload
  3. FineUploader

@ashish 2014-06-23 08:18:49

To upload file asynchronously with Jquery use below steps:

step 1 In your project open Nuget manager and add package (jquery fileupload(only you need to write it in search box it will come up and install it.)) URL: https://github.com/blueimp/jQuery-File-Upload

step 2 Add below scripts in the HTML files, which are already added to the project by running above package:

jquery.ui.widget.js

jquery.iframe-transport.js

jquery.fileupload.js

step 3 Write file upload control as per below code:

<input id="upload" name="upload" type="file" />

step 4 write a js method as uploadFile as below:

 function uploadFile(element) {

            $(element).fileupload({

                dataType: 'json',
                url: '../DocumentUpload/upload',
                autoUpload: true,
                add: function (e, data) {           
                  // write code for implementing, while selecting a file. 
                  // data represents the file data. 
                  //below code triggers the action in mvc controller
                  data.formData =
                                    {
                                     files: data.files[0]
                                    };
                  data.submit();
                },
                done: function (e, data) {          
                   // after file uploaded
                },
                progress: function (e, data) {

                   // progress
                },
                fail: function (e, data) {

                   //fail operation
                },
                stop: function () {

                  code for cancel operation
                }
            });

        };

step 5 In ready function call element file upload to initiate the process as per below:

$(document).ready(function()
{
    uploadFile($('#upload'));

});

step 6 Write MVC controller and Action as per below:

public class DocumentUploadController : Controller
    {       

        [System.Web.Mvc.HttpPost]
        public JsonResult upload(ICollection<HttpPostedFileBase> files)
        {
            bool result = false;

            if (files != null || files.Count > 0)
            {
                try
                {
                    foreach (HttpPostedFileBase file in files)
                    {
                        if (file.ContentLength == 0)
                            throw new Exception("Zero length file!");                       
                        else 
                            //code for saving a file

                    }
                }
                catch (Exception)
                {
                    result = false;
                }
            }


            return new JsonResult()
                {
                    Data=result
                };


        }

    }

@tnt-rox 2014-06-23 18:50:47

Convert file to base64 using |HTML5's readAsDataURL() or some base64 encoder. Fiddle here

var reader = new FileReader();

        reader.onload = function(readerEvt) {
            var binaryString = readerEvt.target.result;
            document.getElementById("base64textarea").value = btoa(binaryString);
        };

        reader.readAsBinaryString(file);

Then to retrieve:

window.open("data:application/octet-stream;base64," + base64);

@Amit 2014-05-12 10:10:03

You can use

$(function() {
    $("#file_upload_1").uploadify({
        height        : 30,
        swf           : '/uploadify/uploadify.swf',
        uploader      : '/uploadify/uploadify.php',
        width         : 120
    });
});

Demo

@farnoush resa 2013-06-16 09:49:29

jQuery Uploadify is another good plugin which I have used before to upload files. The JavaScript code is as simple as the following: code. However, the new version does not work in Internet Explorer.

$('#file_upload').uploadify({
    'swf': '/public/js/uploadify.swf',
    'uploader': '/Upload.ashx?formGuid=' + $('#formGuid').val(),
    'cancelImg': '/public/images/uploadify-cancel.png',
    'multi': true,
    'onQueueComplete': function (queueData) {
        // ...
    },
    'onUploadStart': function (file) {
        // ...
    }
});

I have done a lot of searching and I have come to another solution for uploading files without any plugin and only with ajax. The solution is as below:

$(document).ready(function () {
    $('#btn_Upload').live('click', AjaxFileUpload);
});

function AjaxFileUpload() {
    var fileInput = document.getElementById("#Uploader");
    var file = fileInput.files[0];
    var fd = new FormData();
    fd.append("files", file);
    var xhr = new XMLHttpRequest();
    xhr.open("POST", 'Uploader.ashx');
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
             alert('success');
        }
        else if (uploadResult == 'success')
            alert('error');
    };
    xhr.send(fd);
}

@Ray Nicholus 2016-06-08 17:44:39

Uploadify has been dead for years. Not supported or maintained anymore.

@mpen 2013-02-17 09:34:41

You can do it in vanilla JavaScript pretty easily. Here's a snippet from my current project:

var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(e) {
    var percent = (e.position/ e.totalSize);
    // Render a pretty progress bar
};
xhr.onreadystatechange = function(e) {
    if(this.readyState === 4) {
        // Handle file upload complete
    }
};
xhr.open('POST', '/upload', true);
xhr.setRequestHeader('X-FileName',file.name); // Pass the filename along
xhr.send(file);

@mpen 2013-04-03 15:35:09

@Gary: Sorry, I should have posted that bit too. I was just using the new drag-and-drop functionality in HTML5; you can find an example here: html5demos.com/file-api#view-source -- just click "view source". Essentially, inside the ondrop event you can do var file = e.dataTransfer.files[0]

@Andy 2017-10-31 06:55:18

Perhaps the question has been edited since, but some people on a let's discussion I opened think a vanilla JS answer is off topic if OP asks for a jQuery solution (provided one exists) and such answers belong with a separate question.

@mpen 2017-10-31 16:20:17

@Andy Well I disagree, and it seems 34 others do too. If you can use jQuery, then you can certainly use JavaScript. In any case, this is a community site -- it's not just OP that I'm trying to help here. Everyone is free to choose/use the answer they like best. Some people just gravitate towards jQuery because they think it'll be so much easier/fewer lines of code, when really they don't need the overhead of an extra library at all.

@Techie 2013-01-25 11:03:28

I have been using the below script to upload images which happens to work fine.

HTML

<input id="file" type="file" name="file"/>
<div id="response"></div>

JavaScript

jQuery('document').ready(function(){
    var input = document.getElementById("file");
    var formdata = false;
    if (window.FormData) {
        formdata = new FormData();
    }
    input.addEventListener("change", function (evt) {
        var i = 0, len = this.files.length, img, reader, file;

        for ( ; i < len; i++ ) {
            file = this.files[i];

            if (!!file.type.match(/image.*/)) {
                if ( window.FileReader ) {
                    reader = new FileReader();
                    reader.onloadend = function (e) {
                        //showUploadedItem(e.target.result, file.fileName);
                    };
                    reader.readAsDataURL(file);
                }

                if (formdata) {
                    formdata.append("image", file);
                    formdata.append("extra",'extra-data');
                }

                if (formdata) {
                    jQuery('div#response').html('<br /><img src="ajax-loader.gif"/>');

                    jQuery.ajax({
                        url: "upload.php",
                        type: "POST",
                        data: formdata,
                        processData: false,
                        contentType: false,
                        success: function (res) {
                         jQuery('div#response').html("Successfully uploaded");
                        }
                    });
                }
            }
            else
            {
                alert('Not a vaild image!');
            }
        }

    }, false);
});

Explanation

I use response div to show the uploading animation and response after upload is done.

Best part is you can send extra data such as ids & etc with the file when you use this script. I have mention it extra-data as in the script.

At the PHP level this will work as normal file upload. extra-data can be retrieved as $_POST data.

Here you are not using a plugin and stuff. You can change the code as you want. You are not blindly coding here. This is the core functionality of any jQuery file upload. Actually Javascript.

@Mark 2013-09-22 20:49:45

-1 for using jQuery and not using it's selector engine and event handlers. addEventListener is not cross-browser.

@Mark 2013-11-23 16:14:22

Because it would be pointless to add a separate answer which would be mostly based on this one, with just a few changes. Instead, this answer should be corrected.

@Thiago Negri 2014-01-27 13:57:18

@RainFromHeaven, please, can you edit the answer? I don't know how to do it in the cross-browser way.

@Pierre 2014-06-28 10:48:36

Still does not work in IE 9 and down. Allot of users still use those versions of IE.

@Arbaaz 2015-05-23 05:23:07

Can someone please explain how can this be made to work in asp.net? Do I use webmethod? If yes what would it look like?

@user1091949 2013-06-26 01:12:21

Simple Ajax Uploader is another option:

https://github.com/LPology/Simple-Ajax-Uploader

  • Cross-browser -- works in IE7+, Firefox, Chrome, Safari, Opera
  • Supports multiple, concurrent uploads -- even in non-HTML5 browsers
  • No flash or external CSS -- just one 5Kb Javascript file
  • Optional, built-in support for fully cross-browser progress bars (using PHP's APC extension)
  • Flexible and highly customizable -- use any element as upload button, style your own progress indicators
  • No forms required, just provide an element that will serve as upload button
  • MIT license -- free to use in commercial project

Example usage:

var uploader = new ss.SimpleUpload({
    button: $('#uploadBtn'), // upload button
    url: '/uploadhandler', // URL of server-side upload handler
    name: 'userfile', // parameter name of the uploaded file
    onSubmit: function() {
        this.setProgressBar( $('#progressBar') ); // designate elem as our progress bar
    },
    onComplete: function(file, response) {
        // do whatever after upload is finished
    }
});

@Pierre 2014-06-28 10:53:09

This seems to be the most promising so far, You had me at IE7+! Trying it out now. Thanks

@wbharding 2009-08-13 22:44:39

I've written this up in a Rails environment. It's only about five lines of JavaScript, if you use the lightweight jQuery-form plugin.

The challenge is in getting AJAX upload working as the standard remote_form_for doesn't understand multi-part form submission. It's not going to send the file data Rails seeks back with the AJAX request.

That's where the jQuery-form plugin comes into play.

Here’s the Rails code for it:

<% remote_form_for(:image_form, 
                   :url => { :controller => "blogs", :action => :create_asset }, 
                   :html => { :method => :post, 
                              :id => 'uploadForm', :multipart => true }) 
                                                                        do |f| %>
 Upload a file: <%= f.file_field :uploaded_data %>
<% end %>

Here’s the associated JavaScript:

$('#uploadForm input').change(function(){
 $(this).parent().ajaxSubmit({
  beforeSubmit: function(a,f,o) {
   o.dataType = 'json';
  },
  complete: function(XMLHttpRequest, textStatus) {
   // XMLHttpRequest.responseText will contain the URL of the uploaded image.
   // Put it in an image element you create, or do with it what you will.
   // For example, if you have an image elemtn with id "my_image", then
   //  $('#my_image').attr('src', XMLHttpRequest.responseText);
   // Will set that image tag to display the uploaded image.
  },
 });
});

And here’s the Rails controller action, pretty vanilla:

 @image = Image.new(params[:image_form])
 @image.save
 render :text => @image.public_filename

I’ve been using this for the past few weeks with Bloggity, and it’s worked like a champ.

@Jordan Feldstein 2011-07-29 00:34:20

This AJAX file upload jQuery plugin uploads the file somehwere, and passes the response to a callback, nothing else.

  • It does not depend on specific HTML, just give it a <input type="file">
  • It does not require your server to respond in any particular way
  • It does not matter how many files you use, or where they are on the page

-- Use as little as --

$('#one-specific-file').ajaxfileupload({
  'action': '/upload.php'
});

-- or as much as --

$('input[type="file"]').ajaxfileupload({
  'action': '/upload.php',
  'params': {
    'extra': 'info'
  },
  'onComplete': function(response) {
    console.log('custom handler for file:');
    alert(JSON.stringify(response));
  },
  'onStart': function() {
    if(weWantedTo) return false; // cancels upload
  },
  'onCancel': function() {
    console.log('no file selected');
  }
});

@user840250 2013-03-24 11:31:20

Not working with 1.9.1 :|

@Jordan Feldstein 2013-03-25 17:33:02

@user840250 jQuery 1.9.1?

@Darryl Hein 2008-10-18 19:30:50

A solution I found was to have the <form> target a hidden iFrame. The iFrame can then run JS to display to the user that it's complete (on page load).

@Darryl Hein 2014-09-15 16:59:15

This is what jQuery Form does: malsup.com/jquery/form

@lfender6445 2015-01-30 06:37:07

i am interested in this answer, do you have a demo you can link to?

Related Questions

Sponsored Content

31 Answered Questions

[SOLVED] How do I return the response from an asynchronous call?

18 Answered Questions

[SOLVED] How can I refresh a page with jQuery?

65 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 4776511 View
  • 6007 Score
  • 65 Answer
  • Tags:   javascript arrays

49 Answered Questions

[SOLVED] How do I check if an element is hidden in jQuery?

88 Answered Questions

[SOLVED] How do JavaScript closures work?

52 Answered Questions

[SOLVED] How do I include a JavaScript file in another JavaScript file?

34 Answered Questions

[SOLVED] How do I remove a property from a JavaScript object?

13 Answered Questions

59 Answered Questions

[SOLVED] How do I redirect to another webpage?

48 Answered Questions

Sponsored Content