การกำหนดค่าลักษณะการแคช HTTP

เจฟ พอสนิก
เจฟฟ์ พอสนิก

Codelab นี้จะแสดงวิธีเปลี่ยนส่วนหัวการแคช HTTP ที่แสดงโดยเว็บเซิร์ฟเวอร์ที่ใช้ Node.js โดยเรียกใช้เฟรมเวิร์กการแสดง Express และยังแสดงวิธียืนยันว่ามีการใช้ลักษณะการแคชที่คุณคาดหวังไว้จริงโดยใช้แผงเครือข่ายในเครื่องมือสำหรับนักพัฒนาเว็บของ Chrome

ทำความคุ้นเคยกับโปรเจ็กต์ตัวอย่าง

ไฟล์หลักที่คุณจะนำมาใช้ในโปรเจ็กต์ตัวอย่างมีดังนี้

  • server.js มีโค้ด Node.js ที่แสดงเนื้อหาของเว็บแอป โดยใช้ Express เพื่อจัดการคำขอและการตอบกลับ HTTP กล่าวคือ express.static() จะใช้เพื่อแสดงไฟล์ในเครื่องทั้งหมดในไดเรกทอรีสาธารณะ ดังนั้นเอกสารประกอบของ serve-static จะมีประโยชน์สำหรับคุณ
  • public/index.html คือ HTML ของเว็บแอป เช่นเดียวกับไฟล์ HTML ส่วนใหญ่ คือไม่มีข้อมูลการกำหนดเวอร์ชันอยู่ใน URL
  • public/app.15261a07.js และ public/style.391484cf.css คือเนื้อหา JavaScript และ CSS ของเว็บแอป ไฟล์เหล่านี้จะมีแฮชใน URL ของตัวเอง ที่สอดคล้องกับเนื้อหาของไฟล์ index.html มีหน้าที่ติดตามว่าจะโหลด URL เวอร์ชันใด

กำหนดค่าส่วนหัวของการแคชสำหรับ HTML

เมื่อตอบกลับคำขอสำหรับ URL ที่ไม่มีข้อมูลการกำหนดเวอร์ชัน โปรดตรวจสอบว่าคุณได้เพิ่ม Cache-Control: no-cache ในข้อความตอบกลับแล้ว นอกจากนี้ ขอแนะนำให้ตั้งค่าส่วนหัวการตอบกลับเพิ่มเติม 1 จาก 2 รายการ ได้แก่ Last-Modified หรือ ETag index.html จัดอยู่ในหมวดหมู่นี้ คุณสามารถแบ่งข้อมูลออกเป็น 2 ขั้นตอน

อย่างแรก ส่วนหัว Last-Modified และ ETag จะควบคุมโดยตัวเลือกการกำหนดค่า etag และ lastModified ทั้ง 2 ตัวเลือกเหล่านี้มีค่าเริ่มต้นเป็น true สำหรับการตอบกลับ HTTP ทั้งหมด ดังนั้นในการตั้งค่าปัจจุบันนี้ คุณไม่ต้องเลือกใช้เพื่อดูลักษณะการทำงานดังกล่าว แต่คุณระบุให้ชัดเจนในการกำหนดค่าได้

อย่างที่ 2 คุณต้องเพิ่มส่วนหัว Cache-Control: no-cache ได้ แต่ต้องเป็นเอกสาร HTML เท่านั้น (ในกรณีนี้คือ index.html) วิธีที่ง่ายที่สุดในการตั้งส่วนหัวนี้แบบมีเงื่อนไขคือการเขียน setHeaders function ที่กำหนดเอง และตรวจสอบว่าคำขอที่เข้ามาใหม่เป็นคำขอสำหรับเอกสาร HTML หรือไม่

  • คลิกรีมิกซ์เพื่อแก้ไขเพื่อทำให้โปรเจ็กต์แก้ไขได้

การกำหนดค่าการแสดงผลแบบคงที่ใน server.js จะเริ่มต้นดังนี้

app.use(express.static('public'));
  • ทำการเปลี่ยนแปลงตามที่อธิบายไว้ข้างต้น แล้วคุณจะเห็นทุกอย่างที่มีลักษณะดังนี้
app.use(express.static('public', {
  etag: true, // Just being explicit about the default.
  lastModified: true,  // Just being explicit about the default.
  setHeaders: (res, path) => {
    if (path.endsWith('.html')) {
      // All of the project's HTML files end in .html
      res.setHeader('Cache-Control', 'no-cache');
    }
  },
}));

กำหนดค่าส่วนหัวของการแคชสำหรับ URL ที่มีเวอร์ชัน

เมื่อตอบกลับคำขอสำหรับ URL ที่มี "ลายนิ้วมือ" หรือข้อมูลเวอร์ชัน และเนื้อหาที่ไม่ได้ตั้งใจจะเปลี่ยนแปลง ให้เพิ่ม Cache-Control: max-age=31536000 ลงในการตอบกลับของคุณ app.15261a07.js และ style.391484cf.css จัดอยู่ในหมวดหมู่นี้

โดยต่อยอดจาก setHeaders function ที่ใช้ในขั้นตอนสุดท้าย คุณสามารถใส่ตรรกะเพิ่มเติมเพื่อตรวจสอบว่าคําขอหนึ่งๆ เป็นของ URL ที่มีเวอร์ชันหรือไม่ และหากใช่ ให้เพิ่มส่วนหัว Cache-Control: max-age=31536000

วิธีที่มีประสิทธิภาพที่สุดคือการใช้นิพจน์ทั่วไปเพื่อดูว่าเนื้อหาที่ขอตรงกับรูปแบบเฉพาะที่คุณทราบว่ามีแฮชหรือไม่ ในกรณีของโปรเจ็กต์ตัวอย่างนี้ จะมีอักขระ 8 ตัวจากชุดตัวเลข 0–9 และตัวอักษรพิมพ์เล็ก a–f (นั่นคือ อักขระ hexadecimal) เสมอ ระบบจะคั่นแฮชด้วยอักขระ . ที่ด้านใดด้านหนึ่งเสมอ

นิพจน์ทั่วไปที่ตรงกับกฎทั่วไปเหล่านั้นอาจอยู่ในรูปแบบ new RegExp('\\.[0-9a-f]{8}\\.')

  • แก้ไขฟังก์ชัน setHeaders ให้มีลักษณะดังนี้
app.use(express.static('public', {
  etag: true, // Just being explicit about the default.
  lastModified: true,  // Just being explicit about the default.
  setHeaders: (res, path) => {
    const hashRegExp = new RegExp('\\.[0-9a-f]{8}\\.');

    if (path.endsWith('.html')) {
      // All of the project's HTML files end in .html
      res.setHeader('Cache-Control', 'no-cache');
    } else if (hashRegExp.test(path)) {
      // If the RegExp matched, then we have a versioned URL.
      res.setHeader('Cache-Control', 'max-age=31536000');
    }
  },
}));

ยืนยันลักษณะการทำงานใหม่โดยใช้เครื่องมือสำหรับนักพัฒนาเว็บ

เมื่อแก้ไขเซิร์ฟเวอร์ไฟล์แบบคงที่แล้ว คุณจะตรวจสอบได้ว่ามีการตั้งค่าส่วนหัวที่ถูกต้องหรือไม่ โดยการดูตัวอย่างแอปที่เผยแพร่อยู่โดยเปิดแผง "เครือข่ายเครื่องมือสำหรับนักพัฒนาเว็บ" ไว้

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

  • ปรับแต่งคอลัมน์ที่แสดงในแผงเครือข่ายให้รวมข้อมูลที่เกี่ยวข้องที่สุดด้วยการคลิกขวาที่ส่วนหัวของคอลัมน์ดังนี้

กำหนดค่าแผงเครือข่ายของเครื่องมือสำหรับนักพัฒนาเว็บ

คอลัมน์ที่ควรให้ความสนใจมีดังนี้ Name, Status, Cache-Control, ETag และ Last-Modified

  • ขณะที่เปิดเครื่องมือสำหรับนักพัฒนาเว็บไปยังแผงเครือข่าย ให้รีเฟรชหน้าเว็บ

หลังจากที่โหลดหน้าเว็บแล้ว คุณจะเห็นรายการต่างๆ ในแผงเครือข่ายที่มีลักษณะดังนี้

คอลัมน์แผงเครือข่าย

แถวแรกคือแถวของเอกสาร HTML ที่เข้าไปดู ซึ่งจะมีการให้บริการอย่างถูกต้องกับ Cache-Control: no-cache สถานะการตอบกลับ HTTP สำหรับคำขอนั้นเป็น 304 ซึ่งหมายความว่าเบราว์เซอร์จะรู้ว่าจะไม่ใช้ HTML ที่แคชไว้โดยทันที แต่ได้ส่งคำขอ HTTP ไปยังเว็บเซิร์ฟเวอร์โดยใช้ข้อมูล Last-Modified และ ETag เพื่อดูว่ามีการอัปเดต HTML ที่มีอยู่ในแคชอยู่แล้วหรือไม่ การตอบกลับ HTTP 304 ระบุว่าไม่มี HTML ที่อัปเดต

อีก 2 แถวถัดไปมีไว้สำหรับชิ้นงาน JavaScript และ CSS ที่มีเวอร์ชัน คุณควรเห็นผลลัพธ์ที่แสดงพร้อม Cache-Control: max-age=31536000 และสถานะ HTTP ของแต่ละชื่อคือ 200 เนื่องจากมีการใช้การกำหนดค่า จึงไม่มีคำขอจริงที่ส่งไปยังเซิร์ฟเวอร์ Node.js การคลิกรายการจะแสดงรายละเอียดเพิ่มเติม รวมถึงการตอบกลับว่า "(จากแคชดิสก์)"

สถานะการตอบสนองของเครือข่ายเป็น 200

ค่าจริงสำหรับคอลัมน์ ETag และ Last-Last นั้นไม่สำคัญมากนัก สิ่งสำคัญคือการตรวจสอบว่ากำลังตั้งค่ากฎ

สรุปสิ่งต่างๆ

หลังจากทำตามขั้นตอนใน Codelab นี้แล้ว ตอนนี้คุณก็คุ้นเคยกับวิธีกำหนดค่าส่วนหัวการตอบกลับ HTTP ในเว็บเซิร์ฟเวอร์ที่ใช้ Node.js โดยใช้ Express แล้ว เพื่อใช้แคช HTTP ให้เกิดประโยชน์สูงสุด คุณยังมีขั้นตอนที่ต้องยืนยันว่ามีการใช้ลักษณะการแคชที่คาดไว้ผ่านแผงเครือข่ายในเครื่องมือสำหรับนักพัฒนาเว็บของ Chrome