ติดตั้ง Node.js: ตรวจการทำงานของปุ่มบนเซิร์ฟเวอร์โดยไม่ใช้เบราว์เซอร์

การรัน JavaScript บนเซิร์ฟเวอร์ต้องติดตั้ง Node.js ก่อน ได้ติดตั้ง Node.js 24.21.0 บนเซิร์ฟเวอร์ WordPress ที่ใช้ Nginx และ Apache แล้วใช้ jsdom 30.1.3 ตรวจสคริปต์ปุ่มของหน้าเว็บโดยไม่ใช้เบราว์เซอร์
nodejs ในรีโพสิทอรีพื้นฐานคือ 16.20.2 แต่ jsdom 30.1.3 ที่ใช้ตรวจสคริปต์ต้องใช้ Node.js 22.22.2 ขึ้นไป จึงติดตั้งจากสตรีมโมดูล 24 ของ dnf
1️⃣ จุดประสงค์ของการติดตั้ง Node.js และ jsdom บนเซิร์ฟเวอร์
การตรวจสคริปต์ปุ่มบนเซิร์ฟเวอร์ต้องใช้สองอย่าง คือ Node.js และ jsdom
🔲 Node.js
JavaScript ปกติทำงานในเบราว์เซอร์, แต่เมื่อติดตั้ง Node.js แล้ว เซิร์ฟเวอร์ก็อ่านและรัน JavaScript ได้เช่นกัน
การติดตั้ง Node.js คือการวางตัวรัน JavaScript ที่เคยมีแค่ในเบราว์เซอร์ไว้บนเซิร์ฟเวอร์อีกตัวหนึ่ง Node.js จึงใช้สร้างเว็บเซิร์ฟเวอร์ สร้างคำสั่งที่ประมวลผลหลายไฟล์พร้อมกัน หรือโหลดแพ็กเกจอย่าง jsdom มาตรวจหน้าเว็บ Ghost ก็เป็น CMS ที่ทำงานบน Node.js
🔲 jsdom
jsdom เป็นแพ็กเกจสำหรับ Node.js ที่อ่าน HTML แล้วสร้างเป็นเอกสารที่กดปุ่มได้เหมือนในเบราว์เซอร์ โดยสร้างโครงสร้างเอกสาร (DOM) แบบที่เบราว์เซอร์สร้างตอนเปิดหน้าเว็บไว้ในเซิร์ฟเวอร์โดยไม่มีหน้าจอ สคริปต์จึงหาปุ่มและเปลี่ยนข้อความได้เหมือนอยู่ในเบราว์เซอร์จริง และเพราะไม่ต้องเปิดหน้าต่าง จึงรันบนเซิร์ฟเวอร์ได้ด้วยคำสั่งบรรทัดเดียว
นั่นหมายความว่าการตรวจที่คนเคยต้องเปิดเบราว์เซอร์แล้วกดทีละอย่าง เซิร์ฟเวอร์จะทำแทนด้วยคำสั่ง jsdom จึงใช้ทดสอบการทำงานของปุ่มโดยอัตโนมัติทุกครั้งที่แก้ ดึงเฉพาะเนื้อหาอย่างหัวข้อและลิงก์ออกจากหน้าเว็บ หรือแก้ HTML ของบทความทีเดียวจำนวนมาก
ถ้าดึงหน้าเว็บด้วย PHP หรือ curl จะเห็นแค่ HTML ที่ส่งมาครั้งแรก ข้อความที่เปลี่ยนหลังกดปุ่มจะปรากฏเมื่อสคริปต์ทำงานแล้วเท่านั้น
เบราว์เซอร์ทำงานสี่ขั้น คือ รับหน้าเว็บ อ่านหน้าเว็บ ลองกดปุ่ม และแสดงบนหน้าจอ jsdom ทำทุกขั้นบนเซิร์ฟเวอร์ยกเว้นขั้นแสดงบนหน้าจอ ตำแหน่งและขนาดของปุ่มจึงต้องตรวจในเบราว์เซอร์
2️⃣ ตรวจก่อนติดตั้ง: รีโพสิทอรีพื้นฐานและสตรีมโมดูล
ก่อนรัน [dnf install nodejs] ให้ตรวจก่อนว่าจะได้เวอร์ชันใด nodejs ในรีโพสิทอรีพื้นฐานของ AlmaLinux 9.8 คือ 16.20.2
dnf list --available nodejsAvailable Packages
nodejs.x86_64 1:16.20.2-8.el9_4 appstreamรีโพสิทอรีโมดูลมีสี่สตรีม คือ 18, 20, 22 และ 24 ณ วันที่ตรวจ สตรีม 22 อยู่ที่ 22.23.2 และสตรีม 24 อยู่ที่ 24.21.0
dnf module list nodejsnodejs 18 common [d], development, minimal, s2i Javascript runtime
nodejs 20 common [d], development, minimal, s2i Javascript runtime
nodejs 22 common [d], development, minimal, s2i Javascript runtime
nodejs 24 common [d], development, minimal, s2i Javascript runtimeตามรีจิสทรีของ npm เวอร์ชันที่ jsdom 30.1.3 ต้องการคือ 22.22.2 ขึ้นไปในสาย 22, 24.15.0 ขึ้นไปในสาย 24 หรือ 26 ขึ้นไป สตรีม 22 และ 24 ผ่านเงื่อนไขนี้ทั้งคู่
3️⃣ ติดตั้ง Node.js: dnf module
ครั้งนี้ติดตั้งสตรีม 24 และก่อนรันได้ตรวจรายการแพ็กเกจที่จะติดตั้งด้วยตัวเลือก [--assumeno] ก่อน
dnf module install nodejs:24 --assumenoในรายการมีเพียงห้าแพ็กเกจ คือ nodejs, npm, nodejs-libs, nodejs-docs และ nodejs-full-i18n ไม่มีแพ็กเกจเว็บเซิร์ฟเวอร์ PHP หรือเคอร์เนล เมื่อตรวจแล้วให้ติดตั้งด้วยตัวเลือก [-y]
dnf module install -y nodejs:24Dependencies resolved.
==============================================================================================
Package Architecture Version Repository Size
==============================================================================================
Installing group/module packages:
nodejs x86_64 1:24.21.0-1.module_el9.8.0+321+1555b6a2 appstream 70 k
npm noarch 1:11.19.0-1.24.21.0.1.module_el9.8.0+321+1555b6a2 appstream 2.1 M
Installing dependencies:
nodejs-libs x86_64 1:24.21.0-1.module_el9.8.0+321+1555b6a2 appstream 24 M
Installing weak dependencies:
nodejs-docs noarch 1:24.21.0-1.module_el9.8.0+321+1555b6a2 appstream 5.3 M
nodejs-full-i18n x86_64 1:24.21.0-1.module_el9.8.0+321+1555b6a2 appstream 8.9 M
Installing module profiles:
nodejs/common
Enabling module streams:
nodejs 24
Transaction Summary
==============================================================================================
Install 5 Packages
Total download size: 40 M
Installed size: 185 M[Installing weak dependencies] คือรายการ weak dependencies หรือแพ็กเกจที่ควรติดตั้งไปพร้อมกัน ขนาดดาวน์โหลด 40M และขนาดหลังติดตั้ง 185M
node -vv24.21.0npm -v11.19.0cat /etc/dnf/modules.d/nodejs.module[nodejs]
name=nodejs
stream=24
profiles=common
state=enablednode ติดตั้งเป็น 24.21.0 และ npm เป็น 11.19.0 ไฟล์ตั้งค่าที่เปลี่ยนหลังติดตั้งมีเพียง [/etc/dnf/modules.d/nodejs.module] ซึ่งบันทึกสตรีม 24 และโปรไฟล์ common ว่าเปิดใช้อยู่
4️⃣ ติดตั้ง jsdom และตรวจสคริปต์ปุ่ม
ติดตั้ง jsdom ด้วย npm ลงในโฟลเดอร์งาน และสร้างโฟลเดอร์งานไว้นอกเว็บรูท
mkdir ~/jsdom-test && cd ~/jsdom-test
npm init -y[npm init -y] สร้าง package.json ด้วยค่าเริ่มต้น แล้วติดตั้ง jsdom ลงในโฟลเดอร์เดียวกัน
npm install jsdomadded 36 packages, and audited 37 packages in 2s
8 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilitiesnpm ls jsdomjsdom-test@1.0.0 /root/jsdom-test
└── jsdom@30.1.3ติดตั้งแพ็กเกจ 36 รายการรวม jsdom 30.1.3 แล้ว และช่องโหว่ที่รู้จักเป็น 0 รายการ ขนาดของ node_modules ในโฟลเดอร์งานคือ 26M
node -e 'const { JSDOM } = require(`jsdom`); console.log(new JSDOM(`<h1>สวัสดี</h1>`).window.document.querySelector(`h1`).textContent)'สวัสดีเมื่อ jsdom อ่าน HTML ที่มีแท็ก h1 แท็กเดียวเป็นเอกสาร แล้วพิมพ์ข้อความข้างใน [สวัสดี] ออกมา ก็ถือว่าตรวจการทำงานเสร็จ
การตรวจสคริปต์ปุ่มคือการยืนยันบนเซิร์ฟเวอร์ว่าข้อความเปลี่ยนถูกต้องหลังกด ตัวอย่างนี้สร้างไฟล์ HTML ในโฟลเดอร์งาน ที่เมื่อกดปุ่ม [คัดลอก] ข้อความจะเปลี่ยนเป็น [คัดลอกแล้ว]
cat btn.html<button id="copy">คัดลอก</button>
<script>
document.getElementById('copy').addEventListener('click', function () {
this.textContent = 'คัดลอกแล้ว';
});
</script>สคริปต์ตรวจจะอ่านไฟล์ HTML ด้วย jsdom รันสคริปต์ในไฟล์ แล้วพิมพ์ข้อความก่อนและหลังกดปุ่ม ข้อผิดพลาดของสคริปต์จะพิมพ์เป็นบรรทัดที่ขึ้นต้นด้วย [ข้อผิดพลาด:]
cat check.jsconst fs = require('fs');
const { JSDOM, VirtualConsole } = require('jsdom');
const vc = new VirtualConsole();
vc.on('jsdomError', (e) => console.log('ข้อผิดพลาด:', e.message));
const dom = new JSDOM(fs.readFileSync(process.argv[2], 'utf8'), {
runScripts: 'dangerously',
virtualConsole: vc,
});
const btn = dom.window.document.querySelector('#copy');
console.log('ก่อนกด:', btn.textContent);
btn.click();
console.log('หลังกด:', btn.textContent);node check.js btn.htmlก่อนกด: คัดลอก
หลังกด: คัดลอกแล้วหลังกด ข้อความเปลี่ยนเป็น [คัดลอกแล้ว] จึงยืนยันได้ว่าสคริปต์ปุ่มทำงาน
แค่พิมพ์ผิดตัวเดียวในสคริปต์ ผลก็เปลี่ยน ได้รันการตรวจแบบเดียวกันกับไฟล์ที่เปลี่ยนตัว I พิมพ์ใหญ่ใน getElementById เป็นตัว l พิมพ์เล็ก
sed 's/getElementById/getElementByld/' btn.html > btn-broken.html
node check.js btn-broken.htmlข้อผิดพลาด: Uncaught [TypeError: document.getElementByld is not a function]
ก่อนกด: คัดลอก
หลังกด: คัดลอกข้อผิดพลาดพิมพ์ออกมาที่บรรทัดแรกและสคริปต์หยุด แม้กดปุ่มแล้วข้อความก็ยังเป็น [คัดลอก]
กำหนดความกว้าง 120px และความสูง 40px ให้ปุ่มด้วย CSS แล้วพิมพ์ขนาดออกมา
cat size.jsconst { JSDOM } = require('jsdom');
const dom = new JSDOM('<button id="copy" style="width:120px;height:40px">คัดลอก</button>');
const btn = dom.window.document.querySelector('#copy');
console.log('ความสูง:', btn.offsetHeight, '/ ความกว้าง:', btn.getBoundingClientRect().width);node size.jsความสูง: 0 / ความกว้าง: 0jsdom ไม่มีขั้นวาดบนหน้าจอ ความสูงและความกว้างจึงพิมพ์ออกมาเป็น 0
🔢 FAQ & เนื้อหาแนะนำ







ℹ️ ประกาศเรื่องลิงก์แอฟฟิลิเอต
เนื้อหาของเว็บไซต์นี้มีลิงก์แอฟฟิลิเอต หากผู้เข้าชมซื้อสินค้าหรือบริการผ่านลิงก์เหล่านี้ เว็บไซต์นี้จะได้รับค่าคอมมิชชันจากผู้ขาย ในกระบวนการนี้ ราคาที่ผู้ซื้อจ่าย(ราคาจะลดลงเมื่อมีโปรโมชัน↓)จะไม่สูงขึ้นแต่อย่างใด ราคา ส่วนลด และข้อมูลสต็อกที่แสดงเป็นข้อมูล ณ เวลาที่เขียนและอาจต่างจากความเป็นจริง โปรดตรวจสอบกับผู้ขายอีกครั้งก่อนซื้อ การเลือกและการประเมินสินค้าเขียนตามเกณฑ์ของเราเอง และการได้รับค่าคอมมิชชันหรือไม่ไม่มีผลต่อลำดับการแนะนำหรือเนื้อหาการประเมิน