Gegroet, kameraden. Prachtig op mijn gevechtsservers
Vrienden vroegen me om een ontwikkelingsboerderij voor hen op te zetten, en in plaats van ze mijn specifieke sjablonen te slepen, herinnerde ik me een interessant project
Voordat ik in de bronnen ging graven, keek ik natuurlijk naar waar Chrome het gegenereerde zip-archief met configuraties ophaalt, en daar wachtte een adres dat begint met "blob:" op mij, oeps. Het is al duidelijk geworden dat de dienst onderweg niets genereert, sterker nog, het wordt allemaal gedaan door js. Het zip-archief wordt inderdaad gegenereerd door de client, browser en javascript zelf. Die. het mooie is dat het project
Nadat ik het project had afgerond, begon ik na te denken over wat mijn opties waren. De opgave werd bemoeilijkt door het feit dat ik niet wilde afwijken van de voorwaarde dat het project een pure front-end moest blijven, zonder enige back-end. De eenvoudigste oplossing zou natuurlijk zijn om nodejs op te halen en deze te dwingen een archief met configuraties te genereren met behulp van directe links.
Eigenlijk waren er niet veel opties. Om precies te zijn, er kwam er maar één in me op. We moeten de configuraties instellen en een link krijgen die we naar de serverconsole kunnen kopiëren om een zip-archief te krijgen.
Verschillende tekstbestanden in het resulterende zip-archief wogen nogal wat, letterlijk een paar kilobytes. De voor de hand liggende oplossing was om de base64-string uit het gegenereerde zip-archief te halen en deze in de buffer te gooien, terwijl hij op de server was met de opdracht in de console
echo 'base64string' | base64 --decode > config.zip
we zouden hetzelfde zipbestand kunnen maken.
In de projectbronnen zien we een methode voor het genereren van een zip-archief:
$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',
});
};
alles is vrij eenvoudig, met behulp van de bibliotheek
saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
waarbij inhoud het resulterende blobobject van het zip-archief is.
Oké, het enige dat ik hoefde te doen was er nog een knop naast toevoegen en toen ik erop klikte, zou ik het resulterende zip-archief niet in de browser opslaan, maar de base64-code eruit halen. Na een beetje rommelen, kreeg ik 2 methoden, in plaats van slechts één downloadZip:
$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',
});
};
Zoals je misschien hebt gemerkt, heb ik het genereren van het zip-archief zelf verplaatst naar de privé-genereZip-methode, enzovoort. Dit is AngularJS, en de auteur houdt zich zelf aan callbacks en heeft dit niet via beloften geïmplementeerd. downloadZip deed nog steeds saveAs als uitvoer, terwijl downloadBase64 iets anders deed. We maken een FileReader-object dat in html5 naar ons toekwam en al behoorlijk is
position: absolute;
z-index: -1;
opacity: 0;
waardoor ik het element zowel aan het zicht kon onttrekken als het daadwerkelijk op de pagina kon laten staan. Voila, de taak was voltooid, toen ik op mijn knop klikte, werd een regel als deze in de buffer geplaatst:
echo 'base64string' | base64 --decode > config.zip
die ik eenvoudigweg in de console op de server plakte en onmiddellijk een zip-archief ontving met alle configuraties.
En natuurlijk heb ik een pull-request naar de auteur gestuurd, omdat... het project is actief en levendig, ik zou graag updates van de auteur willen zien en mijn eigen knop hebben) Voor degenen die geïnteresseerd zijn, hier is het
Fijne ontwikkeling allemaal)
Bron: www.habr.com