คุณสามารถใช้ JavaScript เพื่อตรวจสอบว่าแอปของคุณเชื่อมต่อกับอินเทอร์เน็ตหรือไม่
ในบทความนี้ ฉันจะให้คำตอบที่อัปเดตสำหรับคำถามการตรวจหาการเชื่อมต่ออินเทอร์เน็ตนี้ (ต๊าย! พูดว่าเร็วห้าครั้ง!)
โซลูชันนี้จะใช้ Fetch API ของ JavaScript และโค้ดแบบอะซิงโครนัสกับ Async &Await แต่ก่อนอื่น มาดูวิธีแก้ปัญหาที่ยอมรับและอภิปรายว่าเหตุใดจึงอาจไม่ใช่ตัวเลือกที่ดีที่สุดสำหรับการสมัครของคุณ
navigator.onLine
คุณสมบัติออนไลน์ของอินเทอร์เฟซเนวิเกเตอร์ navigator.onLine
มักใช้เพื่อตรวจหาสถานะออนไลน์และออฟไลน์ของเบราว์เซอร์
เมื่อรวมกับผู้ฟังสำหรับเหตุการณ์ออนไลน์และออฟไลน์ ดูเหมือนว่าจะให้โซลูชันที่เรียบง่ายสำหรับนักพัฒนาที่นำไปใช้ได้ง่าย
มาดูว่าเราจะใช้ navigator.onLine อย่างไร
เริ่มต้นด้วยการเพิ่ม Listener เหตุการณ์การโหลด เมื่อเหตุการณ์โหลดเริ่มทำงาน ผู้ฟังจะตรวจสอบคุณสมบัติออนไลน์ของอินเทอร์เฟซเนวิเกเตอร์ แล้วแสดงสถานะออนไลน์
คุณสมบัติออนไลน์ของเนวิเกเตอร์ให้การตอบสนองบูลีน (จริงหรือเท็จ) เพื่อสิ้นสุดการกระทำของผู้ฟัง เราจะใช้คำสั่ง ternary เพื่อตั้งค่าการแสดงสถานะ
window.addEventListener("load", (event) => {
const statusDisplay = document.getElementById("status");
statusDisplay.textContent = navigator.onLine ? "Online" : "OFFline";
});
ทำไมถึงใช้คำว่า navigator? มันคือการอ้างอิงถึงเบราว์เซอร์ Netscape Navigator จากยุค 90
จัดองค์ประกอบ h1 ในหน้า HTML ของคุณให้อยู่ตรงกลางด้วยรหัส "สถานะ" หากคุณใช้โค้ด JavaScript ด้านบนกับหน้าเว็บของคุณ คุณจะเห็นรหัสแสดงเป็น "ออนไลน์"
แต่สิ่งนี้จะอัปเดตองค์ประกอบ h1 เมื่อโหลดหน้าเว็บเท่านั้น มาเพิ่ม Listener เหตุการณ์แบบออฟไลน์และออนไลน์เพื่ออัปเดตการแสดงสถานะเมื่อใดก็ได้ที่เหตุการณ์เหล่านั้นเริ่มทำงาน
window.addEventListener("offline", (event) => {
const statusDisplay = document.getElementById("status");
statusDisplay.textContent = "OFFline";
});
window.addEventListener("online", (event) => {
const statusDisplay = document.getElementById("status");
statusDisplay.textContent = "Online";
});
เราสามารถไปที่แท็บแอปพลิเคชันของ Chrome Dev Tools และคลิกที่ ServiceWorker เพื่อตั้งค่าเบราว์เซอร์ให้ตอบสนองราวกับว่าออฟไลน์
ทำเครื่องหมายและยกเลิกการเลือกช่องทำเครื่องหมายออฟไลน์สองสามครั้ง คุณควรเห็นการแสดงสถานะตอบสนองต่อกิจกรรมออฟไลน์และออนไลน์ที่เริ่มทำงานทันที
มาเจาะลึกกันสักหน่อย
จากความประทับใจครั้งแรก ข้างต้นดูเหมือนจะเป็นทางออกที่ดีซึ่งค่อนข้างง่าย น่าเสียดายที่เมื่อเราอ่านเพิ่มเติมเกี่ยวกับคุณสมบัติออนไลน์ของเนวิเกเตอร์และกิจกรรมออนไลน์และออฟไลน์ เราพบว่ามีปัญหา
การค้นหา navigator.onLine บน CanIUse.com แสดงการสนับสนุนอย่างกว้างขวางสำหรับออนไลน์ | สถานะออฟไลน์ที่คุณสมบัติให้ อย่างไรก็ตาม เมื่อดูหมายเหตุด้านล่างตารางสนับสนุน เราจะเห็นว่า
“ออนไลน์ไม่ได้หมายถึงการเชื่อมต่ออินเทอร์เน็ตเสมอไป นอกจากนี้ยังสามารถหมายถึงการเชื่อมต่อกับบางเครือข่าย”
อืม นั่นทำให้งานยุ่งนิดหน่อย
ดังนั้น หากคุณต้องการทราบสถานะออนไลน์ของเบราว์เซอร์จริงๆ คุณควรพัฒนาวิธีการเพิ่มเติมสำหรับการตรวจสอบ
มาดูการอ้างอิงเอกสาร MDN สำหรับ navigator.onLine ด้วย เอกสารเว็บ MDN สำรองข้อมูล CanIUse.com และเพิ่มหมายเหตุเพิ่มเติม
“เบราว์เซอร์ใช้คุณสมบัตินี้แตกต่างกัน...คุณไม่สามารถสันนิษฐานได้ว่าค่าที่แท้จริงจำเป็นต้องหมายความว่าเบราว์เซอร์สามารถเข้าถึงอินเทอร์เน็ตได้ คุณอาจได้รับผลบวกลวง…”
และนั่นยืนยันความกลัวของเราเกี่ยวกับการใช้คุณสมบัติออนไลน์ของเนวิเกเตอร์เป็นวิธีแก้ปัญหาของเราในการตรวจจับการเชื่อมต่ออินเทอร์เน็ต เป็นโซลูชันที่สามารถสร้างความหายนะในแอปพลิเคชันของเราซึ่งขึ้นอยู่กับการรู้ว่าแหล่งข้อมูลภายนอกพร้อมใช้งานเมื่อใด
ตัวอย่างหนึ่งคือเมื่อเราพยายามตรวจสอบว่า Progressive Web App ออนไลน์อยู่หรือไม่ MDN ยังแนะนำ
“...หากคุณต้องการทราบสถานะออนไลน์ของเบราว์เซอร์จริงๆ คุณควรพัฒนาวิธีการเพิ่มเติมสำหรับการตรวจสอบ”
ค้นหาเว็บอย่างรวดเร็วสำหรับ “เนวิเกเตอร์ออนไลน์ไม่ทำงาน” เผยให้เห็นโพสต์ฟอรั่มต่าง ๆ ที่ผู้ที่ขึ้นอยู่กับคุณสมบัตินี้ประสบปัญหา
แล้ววิธีแก้ปัญหาคืออะไร
เราจำเป็นต้องรู้ว่าเมื่อใดที่แอปพลิเคชันของเราเชื่อมต่อกับอินเทอร์เน็ตอย่างแท้จริง ไม่ใช่แค่เราเตอร์หรือเครือข่ายท้องถิ่น กลับไปที่ไฟล์ JavaScript ของเราแล้วเริ่มใหม่
แนวคิดคือการส่งคำขอและจัดการกับมันอย่างสง่างามโดยจับข้อผิดพลาดหากล้มเหลว หากคำขอสำเร็จ แสดงว่าเรากำลังออนไลน์ แต่ถ้าไม่สำเร็จ แสดงว่าเราไม่ทำ
เราจะขอภาพเล็ก ๆ เป็นระยะเพื่อกำหนดสถานะออนไลน์ Modern JavaScript มี Fetch API และโค้ดแบบอะซิงโครนัสพร้อม Async &Await เราจะใช้เครื่องมือเหล่านี้เพื่อให้บรรลุเป้าหมาย
checkOnlineStatus()
เริ่มต้นด้วยการสร้างฟังก์ชันลูกศรแบบ async ชื่อ checkOnlineStatus ฟังก์ชันจะคืนค่าจริงหรือเท็จเช่นเดียวกับคุณสมบัติออนไลน์ของเนวิเกเตอร์
ภายในฟังก์ชัน เราจะตั้งค่าบล็อกทดลองซึ่งเรารอคำขอดึงข้อมูลสำหรับภาพขนาดหนึ่งพิกเซล ตรวจสอบให้แน่ใจว่าพนักงานบริการของคุณไม่ได้แคชอิมเมจนี้
รหัสตอบกลับ HTTP ระหว่าง 200 ถึง 299 บ่งชี้ความสำเร็จ และเราจะส่งคืนผลลัพธ์ของการเปรียบเทียบรหัสสถานะ สิ่งนี้จะเป็นจริงหากสถานะการตอบสนองอยู่ระหว่าง 200 ถึง 299 และเป็นเท็จ
นอกจากนี้เรายังต้องจัดเตรียมบล็อกดักจับข้อผิดพลาดหากคำขอล้มเหลว เราจะคืนค่า false ในบล็อก catch เพื่อระบุว่าเราออฟไลน์แน่นอนหากสิ่งนี้เกิดขึ้น
const checkOnlineStatus = async () => {
try {
const online = await fetch("/1pixel.png");
return online.status >= 200 && online.status < 300; // either true or false
} catch (err) {
return false; // definitely offline
}
};
ต่อไป เราจะใช้เมธอด setInterval และส่งฟังก์ชัน async ที่ไม่ระบุชื่อ ฟังก์ชัน async จะรอผลของฟังก์ชัน checkOnlineStatus ของเรา จากนั้นเราจะใช้คำสั่ง ternary พร้อมผลลัพธ์เพื่อแสดงสถานะออนไลน์ปัจจุบัน
สำหรับการทดสอบตัวอย่างนี้ ให้ตั้งค่าการหน่วงเวลาเป็นทุกๆ 3 วินาที (3000 มิลลิวินาที) แม้ว่านี่จะบ่อยเกินไป การตรวจสอบทุกๆ 30 วินาที (30000 มิลลิวินาที) อาจเพียงพอสำหรับความต้องการที่แท้จริงของคุณ
setInterval(async () => {
const result = await checkOnlineStatus();
const statusDisplay = document.getElementById("status");
statusDisplay.textContent = result ? "Online" : "OFFline";
}, 3000); // probably too often, try 30000 for every 30 seconds
เมื่อโค้ดใหม่ของเราบันทึกไว้แล้ว เรามาทบทวนแท็บแอปพลิเคชันใน Chrome Dev Tools เพื่อทดสอบการตอบสนองแบบออฟไลน์
ฉันเกือบลืมใส่ตัวฟังเหตุการณ์โหลดด้วยฟังก์ชัน async! การตรวจหาเหตุการณ์การโหลดอาจมีความสำคัญหากคุณมี Progressive Web App ที่ใช้พนักงานบริการเพื่อความพร้อมใช้งานแบบออฟไลน์ มิฉะนั้น หน้าเว็บหรือแอปของคุณจะไม่โหลดหากไม่มีการเชื่อมต่อ
นี่คือตัวฟังเหตุการณ์การโหลดใหม่:
window.addEventListener("load", async (event) => {
const statusDisplay = document.getElementById("status");
statusDisplay.textContent = (await checkOnlineStatus())
? "Online"
: "OFFline";
});
ความคิดสุดท้าย
รหัสช่วงเวลาข้างต้นเหมาะสำหรับการแสดงสถานะการเชื่อมต่อในแอปของคุณ ที่กล่าวว่า ฉันไม่แนะนำให้อาศัยสถานะการเชื่อมต่อที่ได้รับการตรวจสอบ 20 หรือ 30 วินาทีก่อนที่จะทำการร้องขอข้อมูลที่สำคัญในแอปพลิเคชันของคุณ
ดังนั้น คุณควรเรียกใช้ฟังก์ชัน checkOnlineStatus โดยตรงก่อนคำขอและประเมินการตอบสนองก่อนขอข้อมูล
const yourDataRequestFunction = async () => {
const online = await checkOnlineStatus();
if (online) {
// make data request
}
}
บทสรุป
แม้ว่า navigator.onLine จะได้รับการสนับสนุนอย่างกว้างขวาง แต่ก็ให้ผลลัพธ์ที่ไม่น่าเชื่อถือเมื่อพิจารณาว่าแอปพลิเคชันของเราเชื่อมต่อกับอินเทอร์เน็ตจริงๆ หรือไม่ การใช้ Fetch API และ JavaScript แบบอะซิงโครนัส ทำให้เราสามารถเขียนโค้ดโซลูชันที่น่าเชื่อถือยิ่งขึ้นได้อย่างรวดเร็ว
นี่คือลิงก์ไปยังส่วนสำคัญของโค้ดบน GitHub และนี่คือวิดีโอการสอนที่ฉันรวบรวมไว้: