By Conceited Code


2011-01-31 22:36:11 8 Comments

It seems like I have not clearly communicated my problem. I need to send a file (using AJAX) and I need to get the upload progress of the file using the Nginx HttpUploadProgressModule. I need a good solution to this problem. I have tried with the jquery.uploadprogress plugin, but I am finding myself having to rewrite much of it to get it to work in all browsers and to send the file using AJAX.

All I need is the code to do this and it needs to work in all major browsers (Chrome, Safari, FireFox, and IE). It would be even better If I could get a solution that will handle multiple file uploads.

I am using the jquery.uploadprogress plugin to get the upload progress of a file from the NginxHttpUploadProgressModule. This is inside an iframe for a facebook application. It works in firefox, but it fails in chrome/safari.

When I open the console I get this.

Uncaught ReferenceError: progressFrame is not defined
jquery.uploadprogress.js:80

Any idea how I would fix that?

I would like to also send the file using AJAX when it is completed. How would I implement that?

EDIT:
I need this soon and it is important so I am going to put a 100 point bounty on this question. The first person to answer it will receive the 100 points.

EDIT 2:
Jake33 helped me solve the first problem. First person to leave a response with how to send the file with ajax too will receive the 100 points.

2 comments

@Rudie 2011-02-09 10:45:05

Uploading files is actually possible with AJAX these days. Yes, AJAX, not some crappy AJAX wannabes like swf or java.

This example might help you out: https://webblocks.nl/tests/ajax/file-drag-drop.html

(It also includes the drag/drop interface but that's easily ignored.)

Basically what it comes down to is this:

<input id="files" type="file" />

<script>
document.getElementById('files').addEventListener('change', function(e) {
    var file = this.files[0];
    var xhr = new XMLHttpRequest();
    (xhr.upload || xhr).addEventListener('progress', function(e) {
        var done = e.position || e.loaded
        var total = e.totalSize || e.total;
        console.log('xhr progress: ' + Math.round(done/total*100) + '%');
    });
    xhr.addEventListener('load', function(e) {
        console.log('xhr upload complete', e, this.responseText);
    });
    xhr.open('post', '/URL-HERE', true);
    xhr.send(file);
});
</script>

(demo: http://jsfiddle.net/rudiedirkx/jzxmro8r/)

So basically what it comes down to is this =)

xhr.send(file);

Where file is typeof Blob: http://www.w3.org/TR/FileAPI/

Another (better IMO) way is to use FormData. This allows you to 1) name a file, like in a form and 2) send other stuff (files too), like in a form.

var fd = new FormData;
fd.append('photo1', file);
fd.append('photo2', file2);
fd.append('other_data', 'foo bar');
xhr.send(fd);

FormData makes the server code cleaner and more backward compatible (since the request now has the exact same format as normal forms).

All of it is not experimental, but very modern. Chrome 8+ and Firefox 4+ know what to do, but I don't know about any others.

This is how I handled the request (1 image per request) in PHP:

if ( isset($_FILES['file']) ) {
    $filename = basename($_FILES['file']['name']);
    $error = true;

    // Only upload if on my home win dev machine
    if ( isset($_SERVER['WINDIR']) ) {
        $path = 'uploads/'.$filename;
        $error = !move_uploaded_file($_FILES['file']['tmp_name'], $path);
    }

    $rsp = array(
        'error' => $error, // Used in JS
        'filename' => $filename,
        'filepath' => '/tests/uploads/' . $filename, // Web accessible
    );
    echo json_encode($rsp);
    exit;
}

@Rocky 2012-03-08 11:56:37

IE 9 don't know this. :(

@YS. 2012-03-23 00:34:07

This is a feature available only in XMLHttpRequest2, for a full compatibility list - have a look at caniuse.com/xhr2

@vzhen 2013-01-28 07:18:40

@Rudie Do you have the hotblocks.nl tutorial link? not just the demo Thanks in adv

@Rudie 2013-01-28 17:43:16

There's no tutorial. Never wrote it. Didn't even make the demo to be this public.

@Timo Kähkönen 2013-03-24 18:56:28

@Rudie: IE10 seems to support this: caniuse.com/xhr2. IE10 is not that bad. Browser war has some advantages. FF9 seems to be the problematic one when it comes to file uploads: you cannot clear file input!

@Rudie 2013-03-24 20:11:16

Yeah IE10 is much better AND with default automatic updating (but still configurable unfortunately). Let's hope they can keep up with the big boys. (This demo has been working in Chrome for 2+ years btw.) (I actually noted this too some ago.)

@Brock Hensley 2013-05-10 19:23:26

and then????????

@Rudie 2013-05-11 03:14:22

That's not a good question.

@Neil Patrao 2013-06-25 18:45:03

@Rudie Could you please post a simple code for server side handling of the data recieved?

@Rudie 2013-06-26 10:40:11

@NeilMartin I've added PHP example code to the end of the answer. Obviously you'll want to do something else with it.

@jsh 2013-07-31 20:06:02

This took a while to understand but it's sound. One note, if you don't want to upload immediately on form change but have an UPLOAD button you can do something like this (what I ended up doing...) document.getElementById('files').addEventListener('change', function(e) { file = this.files[0]; }, false); $('#mybutton').click(function() { /* ...proceed much as above using the file object from the change listener ... ...}

@Florent2 2013-09-09 19:37:48

I had to use xhr.upload.addEventListener('progress',...) (with .upload) to have the progress indication working.

@Rudie 2013-09-09 22:47:52

@Florent2 That's why there's a xhr.upload.onprogress in there. Weird that onprogress on xhr does something, but not actual progress. (Or at least that's my finding.)

@Florent2 2013-09-10 02:50:39

Thanks Rudie, sorry your code is fine actually, I had missed the if ( xhr.upload ) {... section. Indeed for me too onprogress on xhr without .upload is fired, but only when the upload finishes.

@Arcabard 2014-01-29 18:05:09

Ajax is the crappy wanna be who kicked every ones ass, fantastic post fellow

@Michael 2014-04-14 23:40:06

+1 for not requiring jQuery

@Alexander 2014-06-18 04:27:07

+1 for not requiring jQuery

@drooh 2015-09-21 21:33:04

I'm not sure I understand how to make this work? I would be great if you could make a complete working example and demo online somewhere. Or maybe some guidance on how to make it work and what things are doing?

@Rudie 2015-09-21 23:27:07

@drooh I've simplified the example and added a link to a very simple fiddle. What don't you understand? What doesn't work?

@drooh 2015-09-22 15:16:43

thanks @Rudie for replying, I checked out the fiddle but when I go to select a file nothing happens? That is the part I don't understand? What is missing from this example to make it functional? Forgive me if it's obvious but I'm having trouble connecting the dots.

@Rudie 2015-09-22 16:50:47

@drooh Check the console/JS log/devtools. When nothing happens, it's uploading and logging the progress. You can see what it does in the code. If you can't read that, this is probably too advanced.

@drooh 2015-09-22 17:47:15

@Rudie thanks for that tip, now I can see something is happening. Is there a way for me to send you a private message? I have a form that works using ajax and I'm trying to add a file upload to it. I don't want to get to off topic on this post and add unnecessary comments. I certainly appreciate your help, Im putting in many hours on this and feel I am very close, just need an eye from an expert :) thanks man!

@Yaroslav 2016-10-15 03:16:55

I can see xhr progress: xx% and xhr upload complete in Chrome (version 53) console, but at the server side $_FILES,$_POST and $_GET all is empty arrays. Dо i need to enable something in php to get this work? I'm using php 5.6 builtin server and first example with xhr.send(file);

@Faizan Rupani 2017-08-21 10:24:23

what is file size limit

@jmort253 2011-02-06 10:37:55

Here are some options for using AJAX to upload files:

UPDATE: Here is a JQuery plug-in for Multiple File Uploading.

@Guillaume86 2011-02-09 12:02:56

i used plUpload in several projects with success (multi file upload with progress, supports Flash/Html5/Silverlight etc)

@Adam 2012-03-27 00:13:17

AjaxFileUpload is a piece of crap. It's not compatible with any version of jquery newer than 1.5. Also the code is wicked ugly.

@jmort253 2012-03-28 00:29:20

@Adam - Good to know. I guess a lot changes in a year. Our hair gets a little greyer and JavaScript libraries stop working with newer software versions...

@0plus1 2013-02-25 00:26:11

To expand @Adam, AjaxFileUpload breaks on ie9+

@Adam 2013-03-08 01:26:49

All that complaining aside, it's still my favorite. One of these days I'll get around to rewriting the damn thing and putting it on github.

@Nis 2013-12-04 00:28:19

@jmort253 "Multiple File Uploading" link is not working. Please update or remove.

@Muhammad Usman 2014-06-23 11:21:12

most of the links are not working

@jmort253 2014-06-23 20:33:42

@RanaMuhammadUsman - Take another look now. I believe I found the location of the moved plugins. Hope this helps.

@Muhammad Usman 2014-06-24 13:01:23

Yes links are working now. Thanks

Related Questions

Sponsored Content

53 Answered Questions

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

60 Answered Questions

[SOLVED] How to check whether a checkbox is checked in jQuery?

32 Answered Questions

[SOLVED] How can I upload files asynchronously?

22 Answered Questions

[SOLVED] jQuery Ajax File Upload

40 Answered Questions

[SOLVED] Is there an "exists" function for jQuery?

  • 2008-08-27 19:49:41
  • Jake McGraw
  • 704435 View
  • 2541 Score
  • 40 Answer
  • Tags:   javascript jquery

40 Answered Questions

[SOLVED] Setting "checked" for a checkbox with jQuery?

15 Answered Questions

[SOLVED] "Thinking in AngularJS" if I have a jQuery background?

12 Answered Questions

[SOLVED] Sending multipart/formdata with jQuery.ajax

18 Answered Questions

[SOLVED] Preview an image before it is uploaded

18 Answered Questions

[SOLVED] Abort Ajax requests using jQuery

Sponsored Content