Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Download Multiple Files Without Using Zip File

I have a generic handler Document.ashx that creates Word documents on the fly by reading information from the querystring like this Document.ashx?clientid=123&documentid=10 and it works perfectly.

I need to create an interface with a list of checkboxes and a Download All button. The best idea I've had so far is to use something like this to make the calls to the handler.

$("body").append("<iframe src='Document.ashx?clientid=123&documentid=10'></iframe>
                  <iframe src='Document.ashx?clientid=123&documentid=11'></iframe>")

Chrome and Firefox handle this as expected, though IE9 prompts the user to ask if they want to save the first file but ignores the following files.

How do I initiate downloading of multiple files from the client?

This is for an intranet site so the files are always generated in ~1 second, users would be selecting ~3-5 documents at a time. The vast majority of users are using IE9. I can tell everyone they have to use Firefox or Chrome but I'd rather find a solution that works in all modern browsers.

I don't want to create a zip file server side because then they always have to unzip it first (which will be too difficult for some to understand) and it slows them down.

like image 852
Greg Avatar asked Jan 28 '12 18:01

Greg


People also ask

Why does Google Drive Zip files when downloading?

When you download files from Google Drive, Google will compress them into a single zip file for easy download. However, sometimes, Google Drive gets stuck while zipping files. The common reasons are browser temporarily freezing, computer stuck, network problems, Drive limitations, etc.


2 Answers

So this is propably overkill but works in IE9, FF7, and Chrome 16:

Inspired by this SO post

jQuery Plugins:

  • json2.js
  • $.cookie()
  • $.bbq()

C# in handler:

public void ProcessRequest (HttpContext context) {

    ...

    if (!string.IsNullOrEmpty(context.Request.QueryString["downloadid"])) 
          Response.Cookies[context.Request.QueryString["downloadid"]].Value = "complete";
}

Javascript/jQuery:

function downloadFile(url, downloadid) {
    //set a cookie with a unique download id
    $.cookie(downloadid, 'pending', { path: '/' });

    //create a new url
    var newurl = $.param.querystring(url, { downloadid: downloadid });

    //append an iframe with new url
    $("body").append("<iframe style='height:0;width:0;' data-downloadid='" + downloadid + "' src='" + newurl + "'></iframe>");
}

function downloadComplete(downloadid) {
    //check if download is pending
    return $.cookie(downloadid) == "complete";
}

function downloadManager(arrDownloads) {
    //loop through download items backwards
    var allComplete = false;
    for (var i = arrDownloads.length; i > 0; i--) {
        if (downloadComplete(arrDownloads[i - 1].downloadid)) {
            //download the next one if it exists
            if (i == arrDownloads.length) {
                allComplete = true;
            }
            else {
                downloadFile(arrDownloads[i].url, arrDownloads[i].downloadid);
            }
            //stop checking for completed downloads
            break;
        }
    }

    if (allComplete) {
        //remove cookies
        for (var i = arrDownloads.length; i > 0; i--) {
            $.cookie(arrDownloads[i - 1].downloadid, null, { path: '/' });
        }

        //remove iframes
        $("iframe[data-downloadid]").remove();
    }
    else {
        setTimeout("downloadManager(" + JSON.stringify(arrDownloads) + ");", 500);
    }
}

function downloadFiles(arrurls) {
    var arrDownloads = [];

    for (var i = 0; i < arrurls.length; i++) {
        var item = new Object();
        item.url = arrurls[i];
        item.downloadid = newGuid();
        arrDownloads.push(item);
    }

    //start the first download
    downloadFile(arrDownloads[0].url, arrDownloads[0].downloadid);
    //initiate the manager
    downloadManager(arrDownloads);
}

$(function () {
    var arrurls = [];
    arrurls.push("Document.ashx?clientid=123&documentid=10");
    arrurls.push("Document.ashx?clientid=123&documentid=11");
    arrurls.push("Document.ashx?clientid=123&documentid=12");
    arrurls.push("Document.ashx?clientid=123&documentid=13");
    arrurls.push("Document.ashx?clientid=123&documentid=14");
    downloadFiles(arrurls);
});
like image 92
Greg Avatar answered Oct 09 '22 06:10

Greg


jQuery plugin which will do the work for you:

github.com/biesiad/multiDownload

like image 29
biesiad Avatar answered Oct 09 '22 05:10

biesiad