Ajax CSS

Drag and drop multiple file upload with progress bar

In a previous post i demonstrated how to make Ajax file upload HTML5 drag and drop file upload progress bar which is fine if you are uploading single file, but i found that users are more interested in uploading multiple files at a time. So in this script we will have a look at how to create script which will upload multiple files with progress bar for each upload with drag and drop support.

Great thing is we arent using any flash,swf to achieve our goal HTML5 is enough. Like previous script we will be using HTML5’s File API and HTML5 File Reader Object. I am using Filereader.js jquery plugin instead of manually coding file read function which makes it a much cleaner version, thanks to Brian Grinstead.

You can easily convert the previous script to handle multiple file uploads, Just change the code for XMLHttpRequest() to store each XMLHttpRequest() instance as a distinct object, in this script i have used array index to store the object instances.

Drag and drop multiple file upload with progress bar


drag and drop multi file upload (1684)


    • Hi, ty for your script
      I want use it for multi browsers and to perform on IE i would like to add an browse button to select files. Do you think it s possible with your script ? TY

      • Re,

        I found the solution with the documentation of FileReader JS :

        FileReaderJS.setupInput(document.getElementById(‘file-input’), opts);


  • okay ,I have read all about the f_get_contents(),but now how do i pass the file infor like file size,filename,etc to the php script for echoing to screen

    • Read the file size at the client side using FILE API and send it to server script via same ajax call. In the example “file.size” returns the file size.

  • why are you renaming the file name, yet you already uniquely identified them with the random number id in java script function create_box

    • Its because i didnt want anyone to upload exe file, so no matter what type of file user uploads i forcefully rename it to jpg file. I will suggest you too do not rely on client side javascript validation, validate the file at server side also and then only save that file on disk, User can disable/tweak javascript validation and can upload exe files to your server.

  • can the contents of file_get_contents(‘php://input’) be passed to a function inside a class,like getmyfile->nameof file=file_get_contents(‘php://input’);

  • you have a good approach here but with the f_get_contents() and f_put_contents() ,how are you accounting for memory usage in a very busy file upload system, where many people are actively using it say 1billion.

    • While developing it i didnt consider this case as this was just demonstration of html5 file reader api. My motto was just to demostrate how file reader api can be used.

  • how can i incoporate this example to use a class..My major problem is with the absence of the S_files[ ].where can i get these from the xhr object

    • Why do you want to loop ? it automaticaly tracks the multiple files, I am not sure but while (file_get_contents('php://input') != "") or may be while(strlen(file_get_contents('php://input'))) will work

  • i would like to put in the basic security like check file type against a whitelist of allowed types,file size,content type,etc.And would like to do this using a class.that is why i feel the need to loop through and pass these to my upload class.I need to run the checks on the name ,size and type
    Is this possible?something like this
    $uploader = new Uploader();
    $uploader->setgoodExtensions(array(‘tar’,’tgz’, ‘taz’, ‘z’, ‘gz’, ‘rar’,’txt’)); //allowed extensions list//

  • How can i validate the string of files from the f_get_contents().I have tried it with the $nem=$_SERVER[‘HTTP_X_FILE_NAME’];

    $str = file_get_contents(‘php://input’);

    $valid_ext = validate_extension($ext);
    if($valid_ext=”true” && $valid_sze=”true” ){file_put_contents(“uploads/”.$nem,$str);}else{//do nothing}
    please assist me here
    but it just keeps uploading all files even those with invalid extensions

    • Shad, i really dont have a clue about how it can be done, i need to study it myself because i have hardly worked on php://input, then only i can suggest you how it can done.

  • hi there, I came across this so far:
    function parse_raw_http_request(array &$a_data)
    // read incoming data
    $input = file_get_contents(‘php://input’);

    // grab multipart boundary from content type header
    preg_match(‘/boundary=(.*)$/’, $_SERVER[‘CONTENT_TYPE’], $matches);

    // content type is probably regular form-encoded
    if (!count($matches))
    // we expect regular puts to containt a query string containing data
    parse_str(urldecode($input), $a_data);
    return $a_data;

    $boundary = $matches[1];

    // split content by boundary and get rid of last — element
    $a_blocks = preg_split(“/-+$boundary/”, $input);

    // loop data blocks
    foreach ($a_blocks as $id => $block)
    if (empty($block))

    // you’ll have to var_dump $block to understand this and maybe replace \n or \r with a visibile char

    // parse uploaded files
    if (strpos($block, ‘application/octet-stream’) !== FALSE)
    // match “name”, then everything after “stream” (optional) except for prepending newlines
    preg_match(“/name=\”([^\”]*)\”.*stream[\n|\r]+([^\n\r].*)?$/s”, $block, $matches);
    $a_data[‘files’][$matches[1]] = $matches[2];
    // parse all other fields
    // match “name” and optional value in between newline sequences
    preg_match(‘/name=\”([^\”]*)\”[\n|\r]+([^\n\r].*)?\r$/s’, $block, $matches);
    $a_data[$matches[1]] = $matches[2];
    $a_data = array();
    and displays this:
    array(2) { [“file-input”]=> array(3) { [0]=> string(12) “prototype.js” [1]=> string(11) “msgshow.php” [2]=> string(23) “MOTIVATIONAL LETTER.pdf” } [“submit1”]=> string(6) “submit” }
    how can I pick out only the filename strins from this array???

  • got the data is in an array of arrays and I can get it now.But now how can I alter ths $str variable by deleting from it the filenames that have failed validation???

  • how can I delete from $str
    i have tried this so far but it doesn’t work
    if (in_array( strtolower($ext1), $extensions)) {//if in valid extensions array

    echo $a_data[‘file-input’][$i];

    }else {//delete file from $str
    $mess = str_replace($a_data[‘file-input’][$i],”, $filestring);

    • Shad, i see you are really struggling hard to make this script work, and you are really doing great job by extending this script, but understand that i am not helping you much, But the thing is that my office work keeps me busy too much that i cant enough time for me, not sure if you have noticed or not, but from last 5-6 months i havent posted new post, I am loosing my visitors and google ranking as well.
      Talking about the code you posted, i dont see anything wrong in the code so, save the data in a variable like this $raw_str = $a_data['file-input'][$i] and then print it to see is it holding the right contents and also check the source code to check if there is invalid string in raw data ?

  • Man i got all the arrays,but now how can i alter the $str=f_get_contents(‘php://input’) by deleting the bad files from it.Or how to reconstruct the string without the bad files in it for upload,Or where is the tempname of the files being uploaded? where can i get this from the xhr object???

  • How i can set separate Extensions in var imageType = /image.*/; like var imageType = /image.png/; and ico as well but jpg allowed?image.* will allow all image types

  • Hey bro, its a nice script… But i see if you upload a file using this, you cant remove it. I mean what if a user wants to remove a file after he added the file on the drag n drop place?!

    • I added a few features to this script set, it allows for a list of valid mimeTypes, and then passes the mime type through all the functions to upload(), and changes the post line to this.

      xhr[rand].open(“post”, “ajax_fileupload.php?mimeType=”+encodeURIComponent(mimeType), true);

      likewise you could attach a delete button to each div associated with a file upload, which would execute a post, just like this line, with something like “ajax_delete.php?delete=1&filename=”+encodeURIComponent(mimeType), true); Then just create an ajax_delete.php script which has the line unlink(‘uploads/’.$_GET[‘filename’]) ; Of course this is a bit dangerous, someone could try to hack your site and delete stuff. So you should build in some security.

  • Hi Amit,

    I am using your code for multiple file uploads, its work fine on local machine but showing 500 internal server error while uploading attachment on staging site, our site is on godaddy server. Can you please give us suggestion on this .

    Parag Kamble.

    • There could be many reasons, Check if there is any database error coming up in the code when you run it on server, that can also cause 500 error.

  • I am not a web programmer so snips of code like this from people like you are very useful to me. Thanks!
    I am using this on a password protected page where only myself and one other person will have access to the upload dialog so I am not concerned with any unwanted files being uploaded.
    How can I change this so that the uploaded file retains the original file name and extension?
    Also, is there anything else I should change to allow all file types besides removeing this from script.js ?
    if (!file.type.match(imageType)) {
    alert(“File \””+file.name+”\” is not a valid image file”);
    return false;

      • Thank you for your response but unfortunately I am such a beginner and such a dummy that I have no idea how to implement the code from your link to preserve the file name.
        Thank you anyway for taking the time to respond to me and thank you for sharing this handy code.

  • Hi Amit,
    is it possible to expand this uploader, so you can choose a file by klicking some upload button, so you can browse for the file, without using drag and drop?
    Thanx, Jayden

  • I tried this with both the latest chrome and firefox… fails with more that 3 or 4 files. I do see the correct images on the server. Firefox crashed with 30 files.

    I’m guessing it’s a memory issue. My files are in the 4 to 6M range (images).

    Any thoughts?

Leave a Comment


Notify me of followup comments via e-mail. You can also subscribe without commenting.


Let your friends know what are you reading

Share this post with your friends!