Lassen Sie uns ein nicht triviales Problem lösen. Stellen Sie sich vor, Sie müssen Daten auf elementare Weise über die Benutzeroberfläche herunterladen. Klicken Sie beispielsweise auf die Schaltfläche "Dateien herunterladen".
Nehmen wir die Standardeinstellung Chrome v.88. Die Aufgabe klingt folgendermaßen:
- Generieren Sie clientseitige Dateien.
- Laden Sie alle generierten Dateien mit einem Klick herunter.
Es kann alles sein: eine Reihe von Binärdateien, große Archive mit Backups, eine Bildergalerie und so weiter. Wir werden speziell über den Download-Mechanismus als solchen sprechen, daher werden wir den Download von Text und Bildern als Beispiel nehmen.
Natürlich können Sie dieses Problem lösen, indem Sie einfach alle erforderlichen Dateien in ein ZIP-Archiv komprimieren und dann herunterladen. Es stellt sich heraus, dass der Benutzer eine einzelne Datei herunterlädt, die er dann selbst entpackt. Sie können beispielsweise die jszip-Bibliothek verwenden , mit der Sie eine Reihe von Dateien herunterladen können, indem Sie sie komprimieren.
Hier ist ein kleines Beispiel für einen vorkomprimierten Download aus den Dokumenten:
var zip = new JSZip();
zip.file("Hello.txt", "Hello World\n");
var img = zip.folder("images");
img.file("smile.gif", imgData, {base64: true}); zip.generateAsync({type:"blob"}).then(function(content) {
// see FileSaver.js
saveAs(content, "example.zip"); });
"Wo ist die Nicht-Trivialität hier?" - du fragst. Und du wirst recht haben. Und wenn wir über das gleichzeitige Herunterladen von zwei, drei oder zehn Dateien von der Site sprechen? Beispiel: In der Auswahl befindet sich eine Liste, in der Sie eine bestimmte Anzahl von Dateien zum Herunterladen auswählen können. Lassen Sie uns eine zusätzliche Bedingung einführen: Der Benutzer hat keinen installierten Archivierer, daher verwerfen wir die Option mit Komprimierung in das Archiv. Wie kann man dieses Problem lösen?
Lassen Sie uns zunächst den Browser vorbereiten. Chrome verbietet standardmäßig das Herunterladen von Multifiles. Dies ist aus Sicherheitsgründen. Daher muss diese Funktion zuerst in den Browsereinstellungen entsperrt werden:
- Wir gehen zu den Site-Einstellungen: chrome: // settings / content.
- Gehen Sie zu Zusätzliche Berechtigungen.
- Wählen Sie Automatische Downloads.
- Fügen Sie die gewünschte Site zur Kategorie Zulassen hinzu.
Großartig, jetzt ist Ihr Browser
Ansatz 1 - FileReader
Schauen wir uns den ersten Ansatz am Beispiel des Generierens von Dateien mit FileReader und der Base64-Lese-API an. Ich stelle sofort fest, dass FileReader eine ziemlich umfangreiche API hat. Wählen Sie also, was Ihnen am besten gefällt: Text, ArrayBuffer oder BinaryString.
(function () {
const button = document.getElementById("download_with_reader");
const content = ["content-1", "content-2", "content-3"];
const createLink = () => {
let link = document.createElement('a');
link.download = 'hello.txt';
return link;
}
const generateBlob = () => {
for (const [index, value] of content.entries()) {
const blob = new Blob([value], { type: "text/plain" });
download(blob, index);
}
}
const download = (blob, index) => {
const link = createLink();
let reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = function () {
link.href = reader.result;
link.download = `content-${index+1}.txt`;
link.click();
}
}
button.addEventListener("click", generateBlob);
}) ();
[Code auf Gitlab]
Ansatz 2 - createObjectURL
Sie können auch createObjectURL verwenden - hier können Sie Dateiobjekte oder Blobs speichern.
(function () {
const button = document.getElementById("download_with_url_object");
const content = ["content-1", "content-2", "content-3"];
const createLink = () => {
let link = document.createElement('a');
link.download = 'hello.txt';
return link;
}
const generateBlob = () => {
for (const [index, value] of content.entries()) {
const blob = new Blob([value], { type: "text/plain" });
download(blob, index);
}
}
const download = (blob, index) => {
const link = createLink();
link.href = URL.createObjectURL(blob);
link.download = `content-${index+1}.txt`;
link.click();
URL.revokeObjectURL(link.href);
}
button.addEventListener("click", generateBlob);
}) ();
[Code auf Gitlab]
Ansatz 3 - Download von URL
Die beiden oben genannten Optionen generieren clientseitige Dateien. Dies wird natürlich nicht immer der Fall sein, von Zeit zu Zeit erhalten wir Dateien vom Backend über direkte Links. Dies kann durch Herunterladen von einer URL erfolgen. Chrome erfordert eine Latenz, daher wird die Implementierung einer künstlichen Latenz ein Merkmal dieser Methode.
(function () {
(function () {
const button = document.getElementById("download_with_request");
const urls = ["images/image-1.jpg", "images/image-2.jpg", "images/image-3.jpg"];
const delay = () => new Promise(resolve => setTimeout(resolve, 1000));
const downloadWithRequest = async () => {
for await (const [index, url] of urls.entries()) {
await delay();
const link = document.createElement("a");
link.href = url;
link.download = `image-${index+1}`;
link.click();
}
}
button.addEventListener("click", downloadWithRequest);
}) ();
[Code auf Gitlab]
Gesamt
Hier sind drei recht einfache Möglichkeiten, wie Sie mehrere Dateien gleichzeitig von einer Site herunterladen und schnell erledigen können. Die Hauptsache ist, die erforderlichen Berechtigungen für eine bestimmte Site zu aktivieren und dann die gewünschte Methode auszuwählen.