Salam, kawan. Cantik di server tempur saya telah berjalan sejak tahun 2006 dan selama bertahun-tahun administrasinya saya telah mengumpulkan banyak konfigurasi dan template. Saya sangat memuji nginx dan entah bagaimana ternyata saya bahkan memulai hub nginx di hub juga, pamer m/
Teman-teman meminta saya untuk menyiapkan lahan pengembangan untuk mereka, dan alih-alih menyeret templat spesifik saya kepada mereka, saya teringat sebuah proyek yang menarik , yang menyebarkan konfigurasi di rak dan menyiapkan segalanya untuk memungkinkan enkripsi, dll. Saya pikir, kenapa tidak? Namun, saya marah karena nginxconfig menawarkan saya untuk mengunduh arsip zip ke browser, tanpa mengizinkan saya mengunggahnya langsung ke server menggunakan wget/fetch/curl. Omong kosong, mengapa saya membutuhkannya di browser, saya membutuhkannya di server dari konsol. Marah, saya pergi ke github untuk melihat isi proyek, yang menyebabkan percabangannya dan, sebagai hasilnya, permintaan penarikan. Yang tidak akan saya tulis jika tidak menarik 😉
Tentu saja, sebelum menggali sumbernya, saya melihat di mana Chrome menarik arsip zip yang dihasilkan dengan konfigurasi, dan di sana alamat yang dimulai dengan "gumpalan:" menunggu saya, ups. Sudah menjadi jelas bahwa layanan ini tidak menghasilkan apa pun selama prosesnya, pada kenyataannya, semuanya dilakukan oleh js. Memang arsip zip dihasilkan oleh klien, browser, dan javascript itu sendiri. Itu. keindahannya adalah proyek itu dapat dengan mudah disimpan sebagai halaman html, diunggah ke beberapa dan itu akan berhasil) Ini adalah solusi yang sangat lucu dan menarik, namun sangat merepotkan untuk menyiapkan server, sebenarnya, untuk tujuan pembuatan proyek ini. Unduh arsip yang dihasilkan dengan browser, lalu transfer ke server menggunakan nc... pada tahun 2019? Saya menetapkan tugas untuk menemukan cara mengunduh konfigurasi yang dihasilkan langsung ke server.
Setelah membagi proyek, saya mulai memikirkan apa saja pilihan saya. Tugas ini diperumit oleh kenyataan bahwa saya tidak ingin menyimpang dari ketentuan bahwa proyek harus tetap murni front-end, tanpa back-end. Tentu saja, solusi paling sederhana adalah dengan menarik nodejs dan memaksanya membuat arsip dengan konfigurasi menggunakan tautan langsung.
Sebenarnya tidak banyak pilihan. Lebih tepatnya, hanya satu yang terlintas dalam pikiran. Kita perlu menyiapkan konfigurasi dan mendapatkan tautan yang dapat kita salin ke konsol server untuk mendapatkan arsip zip.
Beberapa file teks dalam arsip zip yang dihasilkan cukup berat, hanya beberapa kilobyte. Solusi yang jelas adalah mendapatkan string base64 dari arsip zip yang dihasilkan dan membuangnya ke buffer, saat berada di server dengan perintah di konsol
echo 'base64string' | base64 --decode > config.zipkita bisa membuat file zip yang sama.
ditulis dalam AngularJS, saya bahkan tidak dapat membayangkan berapa kilometer kode yang diperlukan jika penulis tidak memilih kerangka kerja js yang reaktif. Tapi saya bisa membayangkan betapa lebih sederhana dan indahnya semua ini bisa diimplementasikan di VueJS, meskipun ini adalah topik yang sama sekali berbeda.
Dalam sumber daya proyek kita melihat metode untuk menghasilkan arsip 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',
});
};
semuanya cukup sederhana, menggunakan perpustakaan Zip dibuat tempat file konfigurasi ditempatkan. Setelah membuat arsip zip, js memasukkannya ke browser menggunakan perpustakaan :
saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
di mana konten adalah objek gumpalan yang dihasilkan dari arsip zip.
Oke, yang harus saya lakukan hanyalah menambahkan tombol lain di sebelahnya dan ketika saya mengkliknya, saya tidak akan menyimpan arsip zip yang dihasilkan ke browser, tetapi mendapatkan kode base64 darinya. Setelah mengutak-atik sedikit, saya mendapatkan 2 metode, bukan hanya satu 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',
});
};
Seperti yang mungkin Anda ketahui, saya memindahkan pembuatan arsip zip itu sendiri ke metode generateZip pribadi, dan seterusnya. Ini adalah AngularJS, dan penulisnya sendiri tetap menggunakan callback dan tidak mengimplementasikannya melalui janji. downloadZip masih melakukan saveAs sebagai output, sementara downloadBase64 melakukan sesuatu yang sedikit berbeda. Kami membuat objek FileReader yang datang kepada kami dalam html5 dan sudah cukup untuk digunakan. Yang pada suatu waktu dapat membuat string base64 dari blob, atau lebih tepatnya, membuat string DataURL, tetapi ini tidak begitu penting bagi kami, karena DataURL berisi apa yang kita butuhkan. Bingo, sedikit hambatan menunggu saya ketika saya mencoba memasukkan semua ini ke dalam buffer. Penulis menggunakan perpustakaan dalam proyek ini , yang memungkinkan Anda bekerja dengan clipboard tanpa objek flash, berdasarkan teks yang dipilih. Awalnya, saya memutuskan untuk meletakkan base64 saya di elemen dengan display:none;, tetapi dalam kasus ini saya tidak bisa meletakkannya di clipboard karena tidak terjadi pemisahan. Oleh karena itu, alih-alih display:none; Ya
position: absolute;
z-index: -1;
opacity: 0;
yang memungkinkan saya menyembunyikan elemen dari tampilan dan membiarkannya di halaman. Voila, tugas selesai, ketika saya mengklik tombol saya, baris seperti ini ditempatkan di buffer:
echo 'base64string' | base64 --decode > config.zipyang baru saja saya tempelkan ke konsol di server dan segera menerima arsip zip dengan semua konfigurasinya.
Dan tentu saja saya mengirimkan pull request kepada penulisnya, karena... proyeknya aktif dan hidup, saya ingin melihat pembaruan dari penulis dan memiliki tombol sendiri) Bagi yang berminat, ini dia proyek dan dirinya sendiri , di mana Anda dapat melihat apa yang saya koreksi/tambahkan.
Selamat berkembang semuanya)
Sumber: www.habr.com
