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.


Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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

Inspired by this SO post

jQuery Plugins:

C# in handler:

public void ProcessRequest (HttpContext context) {


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

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

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

        //remove iframes
    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();

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

$(function () {
    var arrurls = [];

Method 2

jQuery plugin which will do the work for you:

Method 3

This may or may not solve your issue, but you’re making a common error here. Iframes are not self-closing tags. Many browsers will not correctly parse this html. Try making it

$("body").append("<iframe src='Document.ashx?clientid=123&documentid=10'>If you can read this, please use a newer browser</iframe>
                  <iframe src='Document.ashx?clientid=123&documentid=11'>If you can read this, please use a newer browser</iframe>")

Also, you way want to try appending each iframe independently, as browsers may not be recognizing the frames correctly when added all at once:
$("body").append("<iframe src='Document.ashx?clientid=123&documentid=10'>If you can read this, please use a newer browser</iframe>");
$("body").append("<iframe src='Document.ashx?clientid=123&documentid=10'>If you can read this, please use a newer browser</iframe>");

Method 4

I know this is an old question, but I have had this issue recently and created this solution which best suited my needs (I did not want to use any cookies and wanted the code to be as simple as possible). In code behind:

Protected Sub DownloadFile(fileId As String)
    If Request.Browser.Browser = "Chrome" Then
        'open iframes dynamically for multiple downloads
        ClientScript.RegisterStartupScript(Me.GetType(), fileId, _
                                           "<script language='javascript'>createIframeForDownloadHandler('" & fileId & "');</script>")
        'open windows for multiple downloads
        ClientScript.RegisterStartupScript(Me.GetType(), fileId, _
                                           "<script language='javascript'>openWindowForDownloadHandler('" & fileId & "');</script>")
    End If
End Sub

Here are the javascript functions:
function openWindowForDownloadHandler(fileId) {
    //open a new window. setting height and width foces new window as opposed to new tab'FileShareDownloadHandler.ashx?id=' + fileId, '_blank', 'width=100,height=100,left=0,top=0');

function createIframeForDownloadHandler(fileId) {
    var element = document.createElement("iframe");
    element.setAttribute('id', 'myframe' + fileId);
    element.setAttribute('style', 'display:none;');
    element.setAttribute('src', 'FileShareDownloadHandler.ashx?id=' + fileId);

Putting DownloadFile(id) inside a loop works well.

Basically, I found chrome works well with handling the iFrames, but IE doesn’t (I am using IE9). This has been working for me on Crome v26, FF v19, IE9.

Method 5

You can call to download in a javascript loop like this:

<a id="downloadAll" href="#" rel="nofollow noreferrer noopener">Download All</a>

var downloadSelected = $('a#downloadSelected');
var doc_ids = ['10', '11'];
for (var i in doc_ids) {
    var uri = 'Document.ashx?clientid=123&documentid=' + doc_ids[i];
    var iframe = $("<iframe/>").attr({
                     src: uri,
                     style: "visibility:hidden;display:none"

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Notify of

Inline Feedbacks
View all comments
Would love your thoughts, please comment.x