Pozdrawiam, towarzysze. Piękne na moich serwerach bojowych
Znajomi poprosili mnie o założenie dla nich farmy deweloperskiej i zamiast przeciągać im moje konkretne szablony, przypomniał mi się ciekawy projekt
Oczywiście przed zagłębieniem się w źródła zajrzałem gdzie Chrome pobiera wygenerowane archiwum zip z konfiguracjami i tam czekał na mnie adres zaczynający się od „blob:”, ups. Stało się już jasne, że usługa po drodze nic nie generuje, tak naprawdę wszystko robi js. Rzeczywiście, archiwum zip jest generowane przez klienta, przeglądarkę i sam JavaScript. Te. piękno polega na tym, że projekt
Po rozwidleniu projektu zacząłem zastanawiać się, jakie mam opcje. Zadanie komplikuje fakt, że nie chciałem odstąpić od warunku, że projekt powinien pozostać czystym frontendem, bez żadnego backendu. Oczywiście najprostszym rozwiązaniem byłoby pobranie nodejs i zmuszenie go do wygenerowania archiwum z konfiguracjami przy użyciu bezpośrednich linków.
Właściwie nie było zbyt wielu opcji. Dokładniej, przyszedł mi do głowy tylko jeden. Musimy skonfigurować konfiguracje i uzyskać link, który możemy skopiować na konsolę serwera, aby uzyskać archiwum ZIP.
Kilka plików tekstowych w powstałym archiwum zip ważyło sporo, dosłownie kilka kilobajtów. Oczywistym rozwiązaniem było pobranie ciągu base64 z wygenerowanego archiwum zip i wrzucenie go do bufora, będąc na serwerze za pomocą polecenia w konsoli
echo 'base64string' | base64 --decode > config.zip
moglibyśmy utworzyć ten sam plik ZIP.
W zasobach projektu widzimy metodę generowania archiwum zip:
$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',
});
};
wszystko jest dość proste, korzystając z biblioteki
saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
gdzie treść jest wynikowym obiektem blob archiwum zip.
Ok, wystarczyło, że dodałem obok niego kolejny przycisk, a kiedy go kliknąłem, nie zapisałem wynikowego archiwum zip w przeglądarce, ale pobrałem z niego kod base64. Po trochę kombinowaniu dostałem 2 metody zamiast jednego 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',
});
};
Jak zapewne zauważyłeś, przeniosłem generowanie samego archiwum zip do prywatnej metody generateZip i tak dalej. To jest AngularJS, a sam autor trzyma się wywołań zwrotnych i nie zaimplementował go poprzez obietnice. downloadZip nadal wykonywał saveAs jako wynik, podczas gdy downloadBase64 zrobił coś nieco innego. Tworzymy obiekt FileReader, który przyszedł do nas w HTML5 i jest już całkiem
position: absolute;
z-index: -1;
opacity: 0;
co pozwoliło mi zarówno ukryć element, jak i pozostawić go na stronie. Voila, zadanie zostało zakończone, kiedy kliknąłem na mój przycisk, w buforze została umieszczona taka linia:
echo 'base64string' | base64 --decode > config.zip
który po prostu wkleiłem do konsoli na serwerze i natychmiast otrzymałem archiwum zip ze wszystkimi konfiguracjami.
I oczywiście wysłałem prośbę o ściągnięcie do autora, ponieważ... projekt jest aktywny i żywy, chciałbym widzieć aktualizacje od autora i mieć własny przycisk) Dla zainteresowanych, tutaj jest
Życzę wszystkim miłego rozwoju)
Źródło: www.habr.com