สวัสดีสหาย สวยงามบนเซิร์ฟเวอร์ต่อสู้ของฉัน
เพื่อนขอให้ฉันสร้างฟาร์มพัฒนาให้พวกเขา และแทนที่จะลากเทมเพลตเฉพาะของฉันไปให้พวกเขา ฉันจำโปรเจ็กต์ที่น่าสนใจได้
แน่นอน ก่อนที่จะเจาะลึกแหล่งที่มา ฉันดูว่า Chrome ดึงไฟล์ zip ที่สร้างขึ้นพร้อมการกำหนดค่าไปที่ใด และมีที่อยู่ที่ขึ้นต้นด้วย "blob:" กำลังรอฉันอยู่ อ๊ะ เป็นที่ชัดเจนแล้วว่าบริการไม่ได้สร้างอะไรเลย ที่จริงแล้ว ทั้งหมดนี้ทำโดย js แท้จริงแล้วไฟล์ zip นั้นถูกสร้างขึ้นโดยไคลเอนต์ เบราว์เซอร์ และจาวาสคริปต์เอง เหล่านั้น. ความสวยงามก็คือโครงการ
หลังจากแยกโปรเจ็กต์แล้ว ฉันเริ่มคิดว่าตัวเลือกของฉันคืออะไร งานมีความซับซ้อนเนื่องจากฉันไม่ต้องการที่จะเบี่ยงเบนไปจากเงื่อนไขที่ว่าโปรเจ็กต์ควรยังคงเป็นส่วนหน้าล้วนๆ โดยไม่มีส่วนหลังใดๆ แน่นอนว่าวิธีแก้ปัญหาที่ง่ายที่สุดคือการดึง nodejs ขึ้นมาและบังคับให้สร้างไฟล์เก็บถาวรด้วยการกำหนดค่าโดยใช้ลิงก์โดยตรง
ที่จริงแล้วมีตัวเลือกไม่มากนัก แม่นยำยิ่งขึ้นมีเพียงคนเดียวเท่านั้นที่อยู่ในใจ เราจำเป็นต้องตั้งค่าคอนฟิกและรับลิงก์ที่เราสามารถคัดลอกไปยังคอนโซลเซิร์ฟเวอร์เพื่อรับไฟล์ zip
ไฟล์ข้อความหลายไฟล์ในไฟล์ zip ที่ได้นั้นมีน้ำหนักไม่น้อย หรือเท่ากับไม่กี่กิโลไบต์เลยทีเดียว วิธีแก้ปัญหาที่ชัดเจนคือการรับสตริง base64 จากไฟล์ zip ที่สร้างขึ้นแล้วโยนลงในบัฟเฟอร์ขณะอยู่บนเซิร์ฟเวอร์ด้วยคำสั่งในคอนโซล
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');
โดยที่ content เป็นวัตถุหยดผลลัพธ์ของไฟล์ zip
ตกลง สิ่งที่ฉันต้องทำคือเพิ่มปุ่มอีกปุ่มหนึ่งข้างๆ และเมื่อฉันคลิกมัน ฉันจะไม่บันทึกไฟล์ 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 และผู้เขียนเองก็ยึดติดกับการโทรกลับและไม่ได้นำไปใช้ผ่านคำสัญญา downloadZip ยังคงทำ saveAs เป็นเอาต์พุต ในขณะที่ downloadBase64 ทำสิ่งที่แตกต่างออกไปเล็กน้อย เราสร้างวัตถุ FileReader ที่มาหาเราใน html5 และค่อนข้างแล้ว
position: absolute;
z-index: -1;
opacity: 0;
ซึ่งทำให้ฉันสามารถซ่อนองค์ประกอบจากมุมมองและปล่อยมันไว้บนหน้าได้ Voila งานเสร็จสมบูรณ์แล้ว เมื่อฉันคลิกที่ปุ่ม บรรทัดแบบนี้ถูกวางไว้ในบัฟเฟอร์:
echo 'base64string' | base64 --decode > config.zip
ซึ่งฉันเพิ่งวางลงในคอนโซลบนเซิร์ฟเวอร์และได้รับไฟล์ zip พร้อมการกำหนดค่าทั้งหมดทันที
และแน่นอน ฉันส่งคำขอดึงไปยังผู้เขียน เพราะ... โครงการมีความกระตือรือร้นและมีชีวิตชีวาฉันต้องการเห็นการอัปเดตจากผู้เขียนและมีปุ่มของตัวเอง) สำหรับผู้ที่สนใจนี่คือ
มีความสุขในการพัฒนาทุกคน)
ที่มา: will.com