Firefox загрузка нескольких файлов одновременно невозможна? - PullRequest
0 голосов
/ 21 мая 2019

Загрузка нескольких BLOB-объектов в Chrome, Edge и IE не кажется проблемой, но в Firefox у меня проблема в том, что в большинстве случаев только последний файл или макс. 2 из них будут «загружены». Я искал код «download blob» и адаптировал его для одновременной загрузки, и проблема воспроизводится на моей машине в последней версии Firefox для Windows 10, см. Код JS ниже в Firefox.

var saveData = (function () {
    var a = document.createElement("a");
    document.body.appendChild(a);
    a.style = "display: none";
    return function (data, fileName) {
        var json = JSON.stringify(data),
            blob = new Blob([json], {type: "octet/stream"}),
            url = window.URL.createObjectURL(blob);
        a.href = url;
        a.download = fileName;
        a.click();
        window.URL.revokeObjectURL(url);
    };
}());

var data = { x: 42, s: "hello, world", d: new Date() },
    fileName = "my-download.json";

saveData(data, fileName);
saveData(data, fileName + 1);
saveData(data, fileName + 2);
saveData(data, fileName + 3);
saveData(data, fileName + 4);
saveData(data, fileName + 5);
saveData(data, fileName + 6);
saveData(data, fileName + 7);

Кажется, что это работает с последующим изменением, но вопрос в том, что было бы реальным профессиональным решением этой проблемы?

var saveData = (function () {
    var a = document.createElement("a");
    document.body.appendChild(a);
    a.style = "display: none";
    return function (data, fileName) {
        var json = JSON.stringify(data),
            blob = new Blob([json], {type: "octet/stream"}),
            url = window.URL.createObjectURL(blob);
        a.href = url;
        a.download = fileName;
        a.click();
        window.URL.revokeObjectURL(url);
    };
}());

var data = { x: 42, s: "hello, world", d: new Date() },
    fileName = "my-download.json";

saveData(data, fileName);
setTimeout(function(){ saveData(data, fileName + 0) }, 1000);
setTimeout(function(){ saveData(data, fileName + 1) }, 2000);
setTimeout(function(){ saveData(data, fileName + 2) }, 3000);

Он также работает с использованием 1,2,3 мс в качестве параметра с таким количеством файлов, но с большим количеством файлов он начал работать с 100 мс, при этом меньшее количество файлов будет «съедено» браузером.

То, что я предполагаю, заключается в том, что у браузеров есть порог, при котором они «объединяют» события щелчка или загрузки, теперь вопрос, каким будет этот порог для каждого браузера, и если есть лучшее решение, чем мой нынешний подход?

1 Ответ

1 голос
/ 22 мая 2019

То, что вы пытаетесь сделать, называется «ковровая бомба».

Она состоит в том, чтобы заполнять диск пользователя большим количеством файлов до тех пор, пока он не исчерпает пространство.
Сам по себеРиск безопасности довольно низок, даже если он может привести к сбою системы, он более скучный, чем любой опасный.
Но, тем не менее, могут быть ситуации, когда он может привести к неожиданному недостатку, как это было в случае Атака «ковер-бомба Safari» .
И, что еще важнее, это редко хороший UX, в котором множество файлов накапливается в папке загрузок вместе с другими несвязанными файлами.

Таким образом, браузеры на самом деле достаточно открыты для решения этой проблемы, и у большинства есть какая-то система, позволяющая избежать этого.


Теперь, вероятно, есть многообходных путей к этим тамперным системам, но я не чувствую, что это то, что вам нужно.

Вы спросили ", есть ли лучшее решение, чем [ваш] текущий подход ", и ответ большой ДА.

Если все ваши файлы доступны длязагрузить одним щелчком мыши, затем упаковать их в один файл для загрузки.

Вы можете сделать это, сгенерировав zip-файл из всех своих BLOB-объектов, используя одну из множества библиотек архивации или даже другой алгоритм сжатия в зависимости отВаши целевые клиенты.

const blobs = "This is a sample text that will get split in chunks of separate text files"
  .split(' ')
  .map((txt) => new Blob([txt])); 

const zip = new JSZip();
const folder = zip.folder('some-words');

blobs.forEach((blob, i) =>
  folder.file(`a-word_${i}.txt`, blob)
);

zip.generateAsync({type : "blob"})
  .then(zip_blob => {
    dl.href = URL.createObjectURL(zip_blob);
    dl.download = "myfiles.zip";
  });
<!-- using JSZip library https://stuk.github.io/jszip/ -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.2.0/jszip.min.js"></script>
<a id="dl">download</a>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...