Salutări, tovarăși. Frumos pe serverele mele de luptă
Prietenii mi-au cerut să înființez o fermă de dezvoltare pentru ei și, în loc să le trag șabloanele mele specifice, mi-am amintit un proiect interesant
Desigur, înainte de a căuta în surse, m-am uitat la locul în care Chrome trage arhiva zip generată cu configurații și acolo mă aștepta o adresă care începe cu „blob:”, hopa. A devenit deja clar că serviciul nu generează nimic pe parcurs, de fapt, totul este făcut de js. Într-adevăr, arhiva zip este generată de client, browser și javascript în sine. Acestea. frumusețea este că proiectul
După ce am întrerupt proiectul, am început să mă gândesc care sunt opțiunile mele. Sarcina a fost complicată de faptul că nu am vrut să mă abat de la condiția ca proiectul să rămână un front-end pur, fără niciun back-end. Desigur, cea mai simplă soluție ar fi să trageți nodejs și să îl forțați să genereze o arhivă cu configurații folosind link-uri directe.
De fapt, nu erau multe opțiuni. Mai exact, doar unul mi-a venit în minte. Trebuie să setăm configurațiile și să obținem un link pe care îl putem copia în consola serverului pentru a obține o arhivă zip.
Câteva fișiere text din arhiva zip rezultată cântăreau destul de mult, literalmente câțiva kiloocteți. Soluția evidentă a fost să obțineți șirul base64 din arhiva zip generată și să-l aruncați în buffer, în timp ce erați pe server cu comanda în consolă
echo 'base64string' | base64 --decode > config.zip
am putea crea același fișier zip.
În resursele proiectului vedem o metodă de generare a unei arhive 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',
});
};
totul este destul de simplu, folosind biblioteca
saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
unde conținutul este obiectul blob rezultat al arhivei zip.
Ok, tot ce trebuia să fac a fost să adaug un alt buton lângă el și când am dat clic pe el, nu salvam arhiva zip rezultată în browser, ci obțineam codul base64 de la ea. După ce m-am jucat puțin, am primit 2 metode, în loc de un singur 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',
});
};
După cum probabil ați observat, am mutat generarea arhivei zip în metoda privată generateZip și așa mai departe. Acesta este AngularJS, iar autorul însuși se limitează la apeluri și nu a implementat-o prin promisiuni. downloadZip încă a salvat ca rezultat, în timp ce downloadBase64 a făcut ceva ușor diferit. Creăm un obiect FileReader care a venit la noi în html5 și este deja destul
position: absolute;
z-index: -1;
opacity: 0;
ceea ce mi-a permis atât să ascund elementul din vedere, cât și să îl las pe pagină. Voila, sarcina a fost finalizată, când am dat clic pe butonul meu, o linie ca aceasta a fost plasată în buffer:
echo 'base64string' | base64 --decode > config.zip
pe care pur și simplu l-am lipit în consola de pe server și am primit imediat o arhivă zip cu toate configurațiile.
Și, bineînțeles, i-am trimis un pull request autorului, pentru că... proiectul este activ și plin de viață, aș dori să văd actualizări de la autor și să am propriul meu buton) Pentru cei interesați, iată-l
Dezvoltare fericită tuturor)
Sursa: www.habr.com