Χαιρετισμούς, σύντροφοι. Όμορφο στους διακομιστές μάχης μου
Φίλοι μου ζήτησαν να δημιουργήσω ένα αγρόκτημα ανάπτυξης για αυτούς και αντί να τους σύρω τα συγκεκριμένα πρότυπά μου, θυμήθηκα ένα ενδιαφέρον έργο
Φυσικά, προτού ψάξω τις πηγές, κοίταξα πού τραβάει ο Chrome το αρχείο zip που δημιουργήθηκε με τις ρυθμίσεις παραμέτρων και εκεί με περίμενε μια διεύθυνση που ξεκινούσε με "blob:", ωχ. Έχει γίνει ήδη σαφές ότι η υπηρεσία δεν δημιουργεί τίποτα στην πορεία, στην πραγματικότητα, όλα γίνονται από το js. Πράγματι, το αρχείο zip δημιουργείται από τον πελάτη, το πρόγραμμα περιήγησης και το ίδιο το javascript. Εκείνοι. η ομορφιά είναι ότι το έργο
Αφού διέλυσα το έργο, άρχισα να σκέφτομαι ποιες ήταν οι επιλογές μου. Το έργο ήταν περίπλοκο από το γεγονός ότι δεν ήθελα να παρεκκλίνω από την προϋπόθεση ότι το έργο θα έπρεπε να παραμείνει ένα καθαρό front-end, χωρίς κανένα back-end. Φυσικά, η απλούστερη λύση θα ήταν να ανακτήσετε το nodej και να το αναγκάσετε να δημιουργήσει ένα αρχείο με ρυθμίσεις παραμέτρων χρησιμοποιώντας άμεσους συνδέσμους.
Στην πραγματικότητα, δεν υπήρχαν πολλές επιλογές. Πιο συγκεκριμένα, μόνο ένα μου ήρθε στο μυαλό. Πρέπει να ρυθμίσουμε τις ρυθμίσεις παραμέτρων και να λάβουμε έναν σύνδεσμο που μπορούμε να αντιγράψουμε στην κονσόλα διακομιστή για να αποκτήσουμε ένα αρχείο zip.
Πολλά αρχεία κειμένου στο αρχείο zip που προέκυψε ζύγιζαν αρκετά, κυριολεκτικά μερικά kilobyte. Η προφανής λύση ήταν να λάβετε τη συμβολοσειρά base64 από το αρχείο zip που δημιουργήθηκε και να την πετάξετε στο buffer, ενώ βρίσκεστε στον διακομιστή με την εντολή στην κονσόλα
echo 'base64string' | base64 --decode > config.zip
θα μπορούσαμε να δημιουργήσουμε αυτό το ίδιο αρχείο zip.
Στους πόρους του έργου βλέπουμε μια μέθοδο για τη δημιουργία ενός αρχείου 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');
όπου το περιεχόμενο είναι το αντικείμενο blob που προκύπτει του αρχείου zip.
Εντάξει, το μόνο που έπρεπε να κάνω ήταν να προσθέσω ένα άλλο κουμπί δίπλα του και όταν έκανα κλικ σε αυτό, δεν θα αποθηκεύσω το αρχείο zip που προέκυψε στο πρόγραμμα περιήγησης, αλλά θα έπαιρνα τον κωδικό base64 από αυτό. Αφού έψαξα λίγο, πήρα 2 μεθόδους, αντί για μία μόνο λήψη Zip:
$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 στη μέθοδο private generateZip και ούτω καθεξής. Αυτό είναι το AngularJS και ο ίδιος ο συγγραφέας εμμένει στις επανακλήσεις και δεν το υλοποίησε μέσω υποσχέσεων. Το downloadZip εξακολουθούσε να έχει saveAs ως έξοδο, ενώ το downloadBase64 έκανε κάτι ελαφρώς διαφορετικό. Δημιουργούμε ένα αντικείμενο FileReader που μας ήρθε σε html5 και είναι ήδη αρκετά
position: absolute;
z-index: -1;
opacity: 0;
που μου επέτρεψε να κρύψω το στοιχείο από την προβολή και να το αφήσω στη σελίδα. Voila, η εργασία ολοκληρώθηκε, όταν έκανα κλικ στο κουμπί μου, μια γραμμή όπως αυτή τοποθετήθηκε στο buffer:
echo 'base64string' | base64 --decode > config.zip
το οποίο απλώς επικολλούσα στην κονσόλα του διακομιστή και έλαβα αμέσως ένα αρχείο zip με όλες τις ρυθμίσεις παραμέτρων.
Και, φυσικά, έστειλα αίτημα έλξης στον συγγραφέα, γιατί... το έργο είναι ενεργό και ζωντανό, θα ήθελα να δω ενημερώσεις από τον συγγραφέα και να έχω το δικό μου κουμπί) Για όσους ενδιαφέρονται, εδώ είναι
Καλή εξέλιξη σε όλους)
Πηγή: www.habr.com