產生 nginx 設定、一個拉取請求的歷史記錄

問候,同志們。 在我的戰鬥伺服器上很漂亮 nginx的 自 2006 年以來一直運行,在管理的這些年裡我積累了許多配置和模板。 我對 nginx 讚不絕口,結果我甚至在集線器上啟動了一個 nginx 集線器,炫耀一下 m/
朋友們讓我為他們建立一個開發農場,我沒有把我的特定模板拖給他們,而是想起了一個有趣的項目 nginxconfig.io,它將配置分散在架子上並為讓加密等做好準備。 我想,為什麼不呢? 然而,令我憤怒的是,nginxconfig 允許我將 zip 檔案下載到瀏覽器中,而不允許我使用 wget/fetch/curl 將其直接上傳到伺服器。 什麼廢話,為什麼我需要在瀏覽器中,我需要從控制台在伺服器上。 憤怒的是,我去了 github 查看該專案的內部結構,這導致了它的分叉,並因此產生了拉取請求。 如果它不有趣我就不會寫😉

產生 nginx 設定、一個拉取請求的歷史記錄

當然,在深入研究原始程式碼之前,我查看了 Chrome 在哪裡使用配置提取生成的 zip 存檔,並且有一個以“blob:”開頭的地址在等著我,哎呀。 已經很清楚了,服務一路上並沒有生成任何東西,事實上,這一切都是由 js 完成的。 事實上,zip 檔案是由客戶端、瀏覽器和 javascript 本身產生的。 那些。 美妙之處在於該項目 nginxconfig.io 可以簡單地儲存為html頁面,上傳到一些 俄羅斯國家報 它會起作用)這是一個非常有趣的解決方案,但是,它對於設定伺服器非常不方便,事實上,正是為了這個專案的創建。 用瀏覽器下載產生的壓縮包,然後用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 使用庫將其提供給瀏覽器 文件保存器.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 設定、一個拉取請求的歷史記錄

來源: www.habr.com

添加評論