awj
awj

Reputation: 7959

Automatic file downloads limited to 10 files on Chrome browser

I have a webpage where we generate PDFs based upon the user selection of on-page items. This causes a postback (it's an ASP.NET WebForms page) which creates the PDFs server-side. An <a class="documentDownload"> tag is then added to the page for each item.

When the page reloads in the browser the following jQuery script is executed to automatically download the files (if the user had chosen a auto-download option):

var divHost = document.createElement("div");
divHost.id = "elmntDnldLinks";
divHost.style.display = "none";
document.body.appendChild(divHost);

setTimeout(function() {
    $(".documentDownload").each(function(idx, val) {

        var lnkDownload = $(val),
            save = document.createElement("a");

        save.href = lnkDownload.attr("href");
        save.download = lnkDownload.attr("download");
        save.target = "_blank";
        divHost.appendChild(save);
        save.click();
    });
}, 1000);

This script has a delay of 1 second, then for each .documentDownload element it creates a new <a> element with the same href attribute of the original element, appends it to a newly-added hidden element, then programmatically clicks it.

[This strategy of creating new links and clicking those instead of clicking the original DOM elements gets around a browser security measure.]

This works perfectly well in Firefox but Chrome never downloads more than 10 files. Why? I can see, for example, 15 links on the page and in the hidden element, but only 10 files are downloaded.

Upvotes: 13

Views: 11675

Answers (3)

Hyunbin
Hyunbin

Reputation: 753

Setting a 200ms delay between each download solves the problem.

Tested on Google Chrome 100.0.4896.127 (Windows, macOS)

Demo in CodePen - 'Download multiple files' should be allowed.

const downloadFileWithAnchor = () => {
  const anchor = document.createElement("a");
  anchor.href = "data:text/plain;charset=utf-8,";
  anchor.download = 'blank.txt';
  document.body.appendChild(anchor);
  anchor.click();
  document.body.removeChild(anchor);
};

const repeatCount = 20;

for (let i = 0; i < repeatCount; i += 1) {
  setTimeout(
    () => {
      downloadFileWithAnchor();
    },
    i * 200 // Delay download every 200ms
  );
}

Upvotes: 4

luisricardo502
luisricardo502

Reputation: 70

You can do a pause in your downloads like that

function sleep(milliseconds) {
    let timeStart = new Date().getTime();
    while (true) {
        let elapsedTime = new Date().getTime() - timeStart;
        if (elapsedTime > milliseconds) {
            break;
        }
    }
}

                    $("#aDescarga")[0].click();
                    $("#aDescarga").attr("href","");

                    if (i > 9) {
                        sleep(2000);
                        i = 0;
                    } else {
                        i = i + 1;
                    }

Upvotes: 0

f2d
f2d

Reputation: 348

If you pause for a second between each 10 downloads, all of them will work in Chrome.

I used async timeout function for this workaround:

function pause(msec) {
    return new Promise(
        (resolve, reject) => {
            setTimeout(resolve, msec || 1000);
        }
    );
}

async function downloadAll(elements) {
    var count = 0;
    for (var e in elements) {

        download(elements[e]); // your custom download code here, click or whatever

        if (++count >= 10) {
            await pause(1000);
            count = 0;
        }
    }
}

Simple timeouts multiplied by element counter could probably work too, but I did not test it.

Upvotes: 23

Related Questions