แก้ไข 404 ที่แอบแฝง

แอปหน้าเดียวสามารถแสดงเนื้อหาที่แตกต่างกันได้โดยไม่ต้องโหลดหน้าใหม่ โดยจะใช้ตัวแฮนเดิลการคลิกในลิงก์และ 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 ใดก็ได้

  • หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกดเต็มหน้าจอ เต็มหน้าจอ

การรีเฟรชและเปิดลิงก์ในหน้าต่างใหม่ที่ไม่ระบุตัวตนควรทํางานได้ตามที่คาดไว้