Вітаю, таварышы. На маіх баявых серверах цудоўны
Сябры папрасілі падняць ім дэвелаперскую ферму і замест таго, каб цягнуць ім свае спецыфічныя шаблоны, я ўспомніў пра цікавы праект
Вядома, перад тым, як калупаць зыходнікі, я паглядзеў адкуль хром цягне згенераваны zip архіў з канфігамі, а там мяне чакаў адрас, які пачынаецца з «blob:», оппа. Ужо стала зразумела, што па ходзе сервіс нічога не генеруе, па факце, што гэта ўсё робіць js. Сапраўды, zip архіў генеруе сам кліент, браўзэр, javascript. Г.зн. хараство ў тым, што праект
Зрабіўшы форк праекту, я пачаў думаць, якія ў мяне ёсць варыянты. Задача ўскладнялася тым, што я не хацеў адыходзіць ад умовы, што праект мусіць заставацца чыстым front-end, без якога-небудзь back-end. Вядома, самае простае рашэнне было б падцягнуць nodejs і прымусіць яго генераваць архіў з канфігамі па прамых спасылках.
Варыянтаў, уласна, было няшмат. Дакладней, у галаву прыйшоў толькі адзін. Нам трэба наладзіць канфігі і атрымаць спасылку, якую зможам скапіяваць у кансоль сервера, каб атрымаць zip архіў.
Некалькі тэкставых файлаў у атрымоўваным zip архіве важылі зусім няшмат, літаральна некалькі кілабайт. Відавочным рашэннем было атрымаць base64 радок са згенераванага zip архіва і кінуць яе ў буфер, тады як на серверы камандай у кансолі
echo 'base64string' | base64 --decode > config.zip
мы маглі б стварыць гэты самы zips файл.
У сурсах праекту мы бачым метад генерацыі 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',
});
};
усё дастаткова проста, з дапамогай бібліятэкі
saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
дзе content, гэта атрыманы blob аб'ект zip архіва.
Ок, усё што мне трэба было зрабіць, гэта дадаць яшчэ адну кнопку побач і пры націску на яе не захоўваць атрыманы zip архіў у браўзэр, а атрымліваць з яго base64 код. Трохі пашаманіўшы, я атрымаў 2 метады, замест аднаго 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',
});
};
Як вы маглі заўважыць, генерацыю самога zip архіва я вынес у прыватны метад generateZip, ну і т.к. гэта AngularJS, ды і сам аўтар прытрымліваецца колбэкаў, не стаў рэалізоўваць яго праз промісы. downloadZip па ранейшаму на выхадзе рабіў saveAs, тады як downloadBase64 рабіў крыху іншае. Мы ствараем FileReader аб'ект, які прыйшоў да нас у html5 і суцэль ужо
position: absolute;
z-index: -1;
opacity: 0;
што дазволіла мне і схаваць элемент з вачэй і па факце пакінуць яго на старонцы. Вуаля, задача выканана, пры націску на маю кнопку, у буфер змяшчаўся радок выгляду:
echo 'base64string' | base64 --decode > config.zip
якую я проста ўстаўляў у кансоль на серверы і тут жа атрымліваў zip архіў са ўсімі канфігамі.
Ну і, вядома, я закінуў pull request аўтару, т.я. праект актыўны і жывы, мне хочацца і абнаўленні ад аўтара бачыць і сваю кнопачку мець ) Каму цікава, вось
Усім бадзёрай распрацоўкі )
Крыніца: habr.com