Tere, sõbrad. Minu võitluss serverites töötab suurepäraselt alates 2006. aastast ja nende aastate jooksul olen kogunud palju konfiguratsioone ja malle. Olen palju kiitnud nginxit ja kuidagi juhtus, et isegi nginx hub'i Habril lõin mina, mures m/
Sõbrad palusid mul üles seada arendustalu ja selle asemel, et tuua neile oma spetsiifilised mallid, meenutasin huvitavat projekti , mis jagab konfiguratsioone riiulitele ja valmistab kõike ette lets encrypt'i jaoks jne. Ja mõtlesin, miks mitte? Siiski häiris mind see, et nginxconfig pakub mulle zip-arhiivi allalaadimist brauseris, võimaldades mul seda otse serverisse wget'i/fetch'i/curl'i kaudu alla laadida. Mis jama see on, miks see on mulle brauseris, ma tahan seda serverisse konsoolist. Kohkunud, kaevandasin GitHub'i, et näha projekti sisu, mis viis selle fork'ini ja seega pull request'ini. Millest ma ei oleks kirjutanud, kui see ei oleks huvitav 😉
Muidugi, enne kui hakkasin allikaid uurima, vaatasin, kust Chrome tõmbab genereeritud zip-arhiivi seadistustega, ja seal ootas mind aadress, mis algas "blob:", opah. Juba oli selge, et teenus ei genereeri midagi, vaid kogu töö teeb javascript. Tõepoolest, zip-arhiivi genereerib klient ise, brauser, javascript. Seega on huvitav, et projekt võib lihtsalt salvestada HTML-lehtena, laadida mõnele ja see töötab ) See on väga naljakas ja huvitav lahendus, kuid see on uskumatult ebamugav serverite seadistamiseks, just selle jaoks, milleks see projekt loodi. Genereritud arhiivi brauseriga alla laadida ja siis edastada see serverisse nc abil ... 2019. aastal? Seadsin eesmärgiks leida viis, kuidas saada saadud seade kohe serverisse.
Tehes projekti fork'i, hakkasin mõtlema, millised on minu valikud. Ülesanne muutus keerulisemaks, kuna ma ei tahtnud minna kaugemale tingimusest, et projekt peaks jääma puhtaks front-endiks, ilma igasuguse back-endita. Muidugi, kõige lihtsam lahendus oleks olnud tuua sisse nodejs ja sundida seda genereerima arhiivi seadistuste otse linkidest.
Valikuid polnud palju. Tõesti, pähe tuli ainult üks. Peame seadistama konfiguratsioonid ja saama lingi, mille saame kopeerida serveri konsooli, et saada zip-arhiiv.
Mõned tekstifailid saadud zip-arhiivis olid väga väikese suurusega, vaid mõned kilobait. Loomulik lahendus oli genereeritud zip-arhivist saada base64 string ja panna see lõikelauale, samal ajal kui serveris konsoolis käsuga
echo 'base64string' | base64 --decode > config.zipme oleksime saanud luua selle zip-faili.
oli kirjutatud AngularJS-is, isegi ei kujuta ette, kui palju koodi oleks vajalik, kui autor ei oleks valinud reaktiivset js raamistikku. Kuid ma kujutan hästi ette, kui lihtne ja ilus oleks see kõik olnud VueJS-is, kuigi see on juba täiesti teine teema.
projekti lähtekoodides näeme zip-arhiivi genereerimise meetodit:
$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',
});
};
Kõik on piisavalt lihtne, kasutades raamatut loodakse zip, kuhu pannakse konfiguratsioonifailid. Pärast zip-arhivi loomist edastab js selle brauserile raamatukogu abil :
saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
kus content on saadud blob-objekt zip-arhivist.
Olgu, kõik, mida mul oli vaja teha, oli lisada veel üks nupp kõrvale ja sellele vajutades mitte salvestada saadud zip-arhivi brauserisse, vaid saada sellest base64 kood. Veidi katsetades sain 2 meetodit, ühe asemel 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,/, '');
// muutuja base64 sisaldab just vajalikku zip arhiivi base64 stringina
}
});
gtag('event', $scope.getDomains().join(','), {
event_category: 'download_base64',
});
};
Nagu olete võinud tähele panna, olen zip-arhiivi genereerimise viinud privaatsetesse meetoditesse, ja kuna tegemist on AngularJS-iga ja autor loobub promise'idest, ei hakka ma seda realiseerima läbi promise'ide. downloadZip teeb endiselt saveAs, samas kui downloadBase64 teeb natuke midagi teistsugust. Loome FileReader objekti, mis tuli meile html5-s ja on täiesti juba Kusjuures, see oskab blob'ist teha base64 stringi, täpsemalt teeb ta DataURL stringi, kuid see pole niivõrd oluline, kuna DataURL sisaldab täpselt seda, mida vajame. Bingo, väike probleem ootas mind, kui proovisin seda kõike lõikesse panna. Autor kasutas projektis raamatukogu , mis võimaldab clipboard’i kasutada ilma flash-objektideta, põhinedes valitud tekstil. Alguses otsustasin panna oma base64 elemendi display:none; alla, kuid sellisel juhul ei saanud ma seda clipboard’i panna, kuna valimine ei toiminud. Seetõttu tegin, selle asemel et kasutada display:none;
position: absolute;
z-index: -1;
opacity: 0;
, mis võimaldas mul elementi varjata ja samas jätta see tegelikult lehele. Voilà, ülesanne on täidetud, mu nupule vajutamisel pandi clipboard’i rida, mis näeb välja nagu:
echo 'base64string' | base64 --decode > config.zip, mille lihtsalt kleepisin serveri konsooli ja sain kohe zip-arhiivi kõikide seadistustega.
Ja muidugi, saatsin pull requesti autorile, kuna projekt on aktiivne ja elujõuline, soovin näha autori uuendusi ja omada oma nuppu ) Kellele see huvi pakub, siin on projektist ja , kus saab vaadata, mida ma parandas/täiendasin.
Kena arendust kõigile )
Allikas: habr.com
