'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.



Solution 1:[1]

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.

Solution 2:[2]

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;
                    }

Solution 3:[3]

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
  );
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 luisricardo502
Solution 3 Hyunbin