Saludos, camaradas. Hermosa en mis servidores de combate
Mis amigos me pidieron que les creara una granja de desarrollo y, en lugar de arrastrarles mis plantillas específicas, recordé un proyecto interesante.
Por supuesto, antes de profundizar en las fuentes, miré de dónde Chrome extrae el archivo zip generado con las configuraciones, y allí me estaba esperando una dirección que comenzaba con “blob:”, ¡ups! Ya ha quedado claro que el servicio no genera nada en el camino, de hecho, todo lo hace js. De hecho, el archivo zip lo genera el cliente, el navegador y el propio javascript. Aquellos. lo bonito es que el proyecto
Después de bifurcar el proyecto, comencé a pensar cuáles eran mis opciones. La tarea se complicó porque no quería desviarme de la condición de que el proyecto siguiera siendo puramente front-end, sin ningún back-end. Por supuesto, la solución más sencilla sería abrir nodejs y obligarlo a generar un archivo con configuraciones mediante enlaces directos.
En realidad, no había muchas opciones. Más precisamente, sólo me vino a la mente uno. Necesitamos configurar las configuraciones y obtener un enlace que podamos copiar a la consola del servidor para obtener un archivo zip.
Varios archivos de texto en el archivo zip resultante pesaban bastante, literalmente unos pocos kilobytes. La solución obvia era obtener la cadena base64 del archivo zip generado y tirarla al búfer, mientras estaba en el servidor con el comando en la consola.
echo 'base64string' | base64 --decode > config.zip
Podríamos crear este mismo archivo zip.
En los recursos del proyecto vemos un método para generar un archivo 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',
});
};
todo es bastante simple, usando la biblioteca
saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
donde contenido es el objeto blob resultante del archivo zip.
Ok, todo lo que tenía que hacer era agregar otro botón al lado y cuando hacía clic en él, no guardaba el archivo zip resultante en el navegador, sino que obtenía el código base64. Después de jugar un poco, obtuve 2 métodos, en lugar de solo un 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',
});
};
Como habrás notado, moví la generación del archivo zip al método privado generateZip, y así sucesivamente. Este es AngularJS, y el propio autor se ciñe a las devoluciones de llamada y no las implementa mediante promesas. downloadZip todavía guardó como salida, mientras que downloadBase64 hizo algo ligeramente diferente. Creamos un objeto FileReader que nos llegó en html5 y ya es bastante
position: absolute;
z-index: -1;
opacity: 0;
lo que me permitió ocultar el elemento a la vista y dejarlo en la página. Listo, la tarea se completó, cuando hice clic en mi botón, se colocó una línea como esta en el búfer:
echo 'base64string' | base64 --decode > config.zip
que simplemente pegué en la consola del servidor e inmediatamente recibí un archivo zip con todas las configuraciones.
Y, por supuesto, envié una solicitud de extracción al autor, porque... el proyecto está activo y animado, me gustaría ver actualizaciones del autor y tener mi propio botón) Para aquellos interesados, aquí está
Feliz desarrollo a todos)
Fuente: habr.com