生成 nginx 配置、一个拉取请求的历史记录

问候,同志们。 在我的战斗服务器上很漂亮 nginx的 自 2006 年以来一直运行,在管理的这些年里我积累了很多配置和模板。 我对 nginx 赞不绝口,结果我什至在集线器上启动了一个 nginx 集线器,炫耀一下 m/
朋友们让我为他们建立一个开发农场,我没有把我的特定模板拖给他们,而是想起了一个有趣的项目 nginxconfig.io,它将配置分散在架子上并为让加密等做好准备。 我想,为什么不呢? 然而,令我愤怒的是,nginxconfig 允许我将 zip 存档下载到浏览器中,而不允许我使用 wget/fetch/curl 将其直接上传到服务器。 什么废话,为什么我需要在浏览器中,我需要从控制台在服务器上。 愤怒的是,我去了 github 查看该项目的内部结构,这导致了它的分叉,并因此产生了拉取请求。 如果它不有趣我就不会写😉

生成 nginx 配置、一个拉取请求的历史记录

当然,在深入研究源代码之前,我查看了 Chrome 在哪里使用配置提取生成的 zip 存档,并且有一个以“blob:”开头的地址在等着我,哎呀。 已经很清楚了,服务一路上并没有生成任何东西,事实上,这一切都是由 js 完成的。 事实上,zip 存档是由客户端、浏览器和 javascript 本身生成的。 那些。 美妙之处在于该项目 nginxconfig.io 可以简单地保存为html页面,上传到一些 narod.ru 它会起作用)这是一个非常有趣的解决方案,但是,它对于设置服务器非常不方便,事实上,正是为了这个项目的创建。 用浏览器下载生成的压缩包,然后用nc传输到服务器...2019? 我给自己设定的任务是找到一种方法将生成的配置直接下载到服务器。
分叉该项目后,我开始思考我的选择是什么。 这项任务很复杂,因为我不想偏离该项目应该保持纯前端、没有任何后端的条件。 当然,最简单的解决方案是拉起 NodeJS 并强制它使用直接链接生成带有配置的存档。
事实上,没有太多选择。 更准确地说,我只想到一个。 我们需要设置配置并获取一个链接,我们可以将其复制到服务器控制台以获取 zip 存档。
生成的 zip 存档中的几个文本文件相当重,实际上有几千字节。 显而易见的解决方案是从生成的 zip 存档中获取 base64 字符串并将其放入缓冲区,同时在服务器上使用控制台中的命令

echo 'base64string' | base64 --decode > config.zip

我们可以创建同样的 zip 文件。

nginxconfig.io 是用 AngularJS 编写的,我什至无法想象如果作者没有选择响应式 js 框架,需要多少公里的代码。 但我完全可以想象这一切在 VueJS 中可以实现多么简单和美丽,尽管这是一个完全不同的话题。
在项目资源中我们看到了生成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',
	});
};

一切都很简单,使用库 压缩包 将在放置配置文件的位置创建一个 zip。 创建 zip 存档后,js 使用库将其提供给浏览器 文件保护程序:

saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');

其中 content 是 zip 存档的结果 blob 对象。

好吧,我所要做的就是在它旁边添加另一个按钮,当我单击它时,我不会将生成的 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,作者本人坚持回调,并没有通过promise来实现。 downloadZip 仍然将 saveAs 作为输出,而 downloadBase64 的做法略有不同。 我们创建了一个 FileReader 对象,它是在 html5 中出现的,并且已经相当好了 可得到 用来。 其中,一次可以从 blob 生成一个 base64 字符串,或者更确切地说,它生成一个 DataURL 字符串,但这对我们来说并不那么重要,因为DataURL 正是我们所需要的。 宾果,当我试图将所有这些放入缓冲区时,有一个小障碍在等着我。 作者在项目中使用了该库 剪贴板js,它允许您根据选定的文本在没有 Flash 对象的情况下使用剪贴板。 最初,我决定将我的 base64 放入带有 display:none; 的元素中,但在这种情况下,我无法将其放在剪贴板上,因为不会发生分离。 因此,不要显示:none; 我做到了

position: absolute;
z-index: -1;
opacity: 0;

这使我既可以从视图中隐藏元素,又可以将其实际保留在页面上。 瞧,任务完成了,当我单击按钮时,缓冲区中放置了这样一行:

echo 'base64string' | base64 --decode > config.zip

我只是将其粘贴到服务器上的控制台中,并立即收到包含所有配置的 zip 存档。
当然,我向作者发送了拉取请求,因为...... 该项目非常活跃,我希望看到作者的更新并拥有自己的按钮)对于那些感兴趣的人,这里是 我的叉子 项目和他自己 拉请求,您可以在其中看到我更正/添加的内容。
祝大家发展愉快)

生成 nginx 配置、一个拉取请求的历史记录

来源: habr.com

添加评论