Grüße, Kameraden. Wunderschön auf meinen Kampfservern
Freunde baten mich, eine Entwicklungsfarm für sie einzurichten, und anstatt ihnen meine spezifischen Vorlagen zu übertragen, fiel mir ein interessantes Projekt ein
Bevor ich mich mit den Quellen befasst habe, habe ich mir natürlich angeschaut, wo Chrome das generierte ZIP-Archiv mit den Konfigurationen abruft, und dort wartete eine Adresse, die mit „blob:“ begann, auf mich, ups. Es ist bereits klar geworden, dass der Dienst unterwegs nichts generiert, sondern alles von js erledigt wird. Tatsächlich wird das Zip-Archiv vom Client, Browser und Javascript selbst generiert. Diese. Das Schöne ist, dass das Projekt
Nachdem ich das Projekt geforkt hatte, begann ich darüber nachzudenken, welche Optionen ich hätte. Die Aufgabe wurde dadurch erschwert, dass ich nicht von der Bedingung abweichen wollte, dass das Projekt ein reines Frontend bleiben sollte, ohne jegliches Backend. Die einfachste Lösung wäre natürlich, nodejs aufzurufen und zu zwingen, über direkte Links ein Archiv mit Konfigurationen zu generieren.
Eigentlich gab es nicht viele Möglichkeiten. Genauer gesagt fiel mir nur eines ein. Wir müssen die Konfigurationen einrichten und einen Link erhalten, den wir auf die Serverkonsole kopieren können, um ein Zip-Archiv zu erhalten.
Mehrere Textdateien im resultierenden Zip-Archiv wogen ziemlich viel, buchstäblich ein paar Kilobyte. Die offensichtliche Lösung bestand darin, die Base64-Zeichenfolge aus dem generierten ZIP-Archiv abzurufen und sie mit dem Befehl in der Konsole auf dem Server in den Puffer zu werfen
echo 'base64string' | base64 --decode > config.zip
Wir könnten dieselbe ZIP-Datei erstellen.
In den Projektressourcen sehen wir eine Methode zum Generieren eines Zip-Archivs:
$scope.downloadZip = function() {
var zip = new JSZip();
var sourceCodes = $window.document.querySelectorAll('main .file .code.source');
for (var i = 0; i < sourceCodes.length; i++) {
var sourceCode = sourceCodes[i];
var name = sourceCode.dataset.filename;
var content = sourceCode.children[0].children[0].innerText;
if (!$scope.isSymlink() && name.match(/^sites-available//)) {
name = name.replace(/^sites-available//, 'sites-enabled/');
}
zip.file(name, content);
if (name.match(/^sites-available//)) {
zip.file(name.replace(/^sites-available//, 'sites-enabled/'), '../' + name, {
unixPermissions: parseInt('120755', 8),
});
}
}
zip.generateAsync({
type: 'blob',
platform: 'UNIX',
}).then(function(content) {
saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
});
gtag('event', $scope.getDomains().join(','), {
event_category: 'download_zip',
});
};
Mit der Bibliothek ist alles ganz einfach
saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
Dabei ist Inhalt das resultierende Blob-Objekt des ZIP-Archivs.
Ok, ich musste nur noch eine weitere Schaltfläche daneben hinzufügen und wenn ich darauf klickte, speicherte ich das resultierende Zip-Archiv nicht im Browser, sondern holte den Base64-Code daraus. Nachdem ich ein wenig herumgespielt hatte, bekam ich statt nur einer downloadZip zwei Methoden:
$scope.downloadZip = function() {
generateZip(function (content) {
saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
});
gtag('event', $scope.getDomains().join(','), {
event_category: 'download_zip',
});
};
$scope.downloadBase64 = function() {
generateZip(function (content) {
var reader = new FileReader();
reader.readAsDataURL(content);
reader.onloadend = function() {
var base64 = reader.result.replace(/^data:.+;base64,/, '');
// в переменной base64 как раз нужный мне zip архив в виде base64 строки
}
});
gtag('event', $scope.getDomains().join(','), {
event_category: 'download_base64',
});
};
Wie Sie vielleicht bemerkt haben, habe ich die Generierung des Zip-Archivs selbst auf die private Methode „generateZip“ usw. verschoben. Das ist AngularJS, und der Autor selbst hält sich an Rückrufe und hat es nicht durch Versprechen umgesetzt. downloadZip führte immer noch saveAs als Ausgabe aus, während downloadBase64 etwas etwas anderes tat. Wir erstellen ein FileReader-Objekt, das in HTML5 zu uns kam und bereits recht ist
position: absolute;
z-index: -1;
opacity: 0;
Dadurch konnte ich das Element sowohl ausblenden als auch tatsächlich auf der Seite belassen. Voila, die Aufgabe war erledigt, als ich auf meinen Button klickte, wurde eine Zeile wie diese im Puffer abgelegt:
echo 'base64string' | base64 --decode > config.zip
die ich einfach in die Konsole auf dem Server eingefügt habe und sofort ein Zip-Archiv mit allen Konfigurationen erhalten habe.
Und natürlich habe ich eine Pull-Anfrage an den Autor gesendet, weil ... Das Projekt ist aktiv und lebendig, ich würde gerne Updates vom Autor sehen und einen eigenen Button haben) Für Interessierte, hier ist es
Allen eine gute Entwicklung)
Source: habr.com