แอปหน้าเดียวสามารถแสดงเนื้อหาที่แตกต่างกันได้โดยไม่ต้องโหลดหน้าใหม่ โดยใช้เครื่องจัดการการคลิกในลิงก์และ History API History API ช่วยให้คุณจัดการประวัติเซสชันของเบราว์เซอร์ได้ วิธีนี้ช่วยให้เราอัปเดต URL ได้เมื่อแสดงหน้าอื่น (โดยปกติจะเรียกว่า "ยอดดู" ในแอปหน้าเดียว) นอกจากนี้ยังช่วยให้มั่นใจว่าปุ่มย้อนกลับของเบราว์เซอร์ยังคงทำงานตามที่คาดไว้
ดูแอปหน้าเดียวใน Codelab นี้ โดยจะแสดงรูปภาพแมวหรือสุนัข และมีลิงก์สำหรับสลับไปมาระหว่างสัตว์ทั้ง 2 ชนิด ดูเหมือนว่าจะใช้งานได้ดี
การค้นหา 404 ที่ซ่อนอยู่
แต่แอปนี้มีข้อบกพร่องเล็กน้อย มาดูกันว่าคืออะไร
- หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกดเต็มหน้าจอ
- คลิกลิงก์ Doggos สังเกตว่า URL มีการเปลี่ยนแปลงอย่างไร
- โหลดแอปซ้ำ
คุณจะเห็นหน้าที่มีข้อความ "Cannot GET /doggos" ซึ่งเป็น 404 แอบแฝง ซึ่งเป็นปัญหาที่ "ตรวจจับได้ยาก" เนื่องจากเว็บแอปดูเหมือนจะทำงานได้ดีตราบใดที่คุณคลิกลิงก์ภายในเว็บแอปเท่านั้น โดยจะใช้งานไม่ได้เมื่อใช้ URL ในหน้าต่างเบราว์เซอร์ใหม่หรือเมื่อรีเฟรชหน้าเว็บ ปัญหาคือเซิร์ฟเวอร์ไม่ทราบวิธีตอบสนองต่อคำขอสำหรับ URL เหล่านี้ โค้ด JavaScript ในเว็บแอปของเราใช้ History API เพื่อไปยังส่วนต่างๆ ระหว่าง URL แต่เซิร์ฟเวอร์ไม่ทราบว่าจะทำอย่างไรกับ URL เหล่านี้
เมื่อใดก็ตามที่เซิร์ฟเวอร์ไม่ทราบว่าต้องทำอย่างไรกับ URL ที่ขอ เซิร์ฟเวอร์จะตอบกลับด้วยรหัสสถานะ HTTP 404 รหัสนี้หมายความว่าเซิร์ฟเวอร์ไม่พบข้อมูลใดๆ สำหรับ URL ที่ขอ
เครื่องมือค้นหาจะไม่จัดทำดัชนี URL ในกรณีนี้ เนื่องจากผู้ใช้จะคลิกผลการค้นหาและพบข้อความแสดงข้อผิดพลาด แต่ไม่พบเนื้อหาที่ต้องการ เช่น รูปภาพสุนัข
การแก้ไขเซิร์ฟเวอร์
โปรเจ็กต์นี้ใช้เซิร์ฟเวอร์ express.js ที่เขียนด้วย JavaScript มาแก้ไขเซิร์ฟเวอร์เพื่อให้ตอบสนองด้วย index.html และแอปหน้าเดียวจะจัดการส่วนที่เหลือเอง
- คลิกรีมิกซ์เพื่อแก้ไขเพื่อให้โปรเจ็กต์แก้ไขได้
- เลือกไฟล์
server.js
ไฟล์นี้มีโค้ดเซิร์ฟเวอร์ โดยจะตั้งค่าเซิร์ฟเวอร์ express.js และส่งเนื้อหาของ index.html การตั้งค่าเส้นทางในบรรทัดที่ 15 จะแสดงเว็บแอปเมื่อคำขอไปยัง URL / เท่านั้น เซิร์ฟเวอร์ควรแสดง URL อื่นๆ ที่เราสร้างขึ้นด้วย มาเปลี่ยนเป็นแสดง URL ทั้งหมดกัน เพื่อให้ใช้กับ URL เพิ่มเติมในอนาคตได้ด้วย
ซึ่งทำได้โดยเปลี่ยนโค้ดตั้งแต่บรรทัดที่ 15 เป็นโค้ดต่อไปนี้
app.get('/*', function(request, response) {
response.sendFile(__dirname + '/views/index.html');
});
/* จะจับคู่กับ URL ใดก็ได้ และตอนนี้เซิร์ฟเวอร์จะตอบสนองด้วยเว็บแอปใน index.html สำหรับ URL ที่ระบุ
- หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกดเต็มหน้าจอ
ตอนนี้การรีเฟรชและการเปิดลิงก์ในหน้าต่างที่ไม่ระบุตัวตนใหม่ควรทำงานได้ตามที่คาดไว้แล้ว