ضبط سلوك تخزين HTTP

يوضِّح لك هذا الدرس التطبيقي حول الترميز كيفية تغيير رؤوس التخزين المؤقت لبروتوكول 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 إلى رسائل الردّ. بالإضافة إلى ذلك، يُنصَح بإعداد أحد عنوانَي الاستجابة الإضافيَين: Last-Modified أو ETag. يندرج index.html ضمن هذه الفئة. يمكنك تقسيم هذا إلى خطوتين.

أولاً، يتم التحكّم في عنوانَي Last-Modified وETag من خلال خيارات ضبط etag وlastModified. يتم ضبط كلا الخيارين تلقائيًا على true لجميع استجابات HTTP، وبالتالي في هذا الإعداد الحالي، ليس يجب الموافقة على تفعيل هذا السلوك. ولكن يمكنك أن تكون صريحًا في الإعدادات على أي حال.

ثانيًا، يجب أن تكون قادرًا على الإضافة في عنوان 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.

تتمثّل الطريقة الأكثر فعالية لإجراء ذلك في استخدام تعبير عادي لمعرفة ما إذا كانت مادة العرض المطلوبة تتطابق مع نمط معيّن تعرف أنّ علامات التجزئة تندرج ضمنه. في حالة نموذج المشروع هذا، تتألف كلمة المرور دائمًا من ثمانية أحرف من مجموعة الأرقام من 0 إلى 9 والأحرف الصغيرة من a إلى f (أي الأحرف السداسية العشرية). ويتم دائمًا فصل التجزئة باستخدام حرف . على كلا الجانبَين.

ويمكن التعبير عن التعبير العادي الذي يطابق هذه القواعد العامة بالصيغة 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 لمعرفة ما إذا كان هناك أي تحديث يتضمّنه حاليًا في ذاكرة التخزين المؤقت. تشير استجابة HTTP 304 إلى عدم توفّر رمز HTML محدّث.

الصفان التاليان مخصّصان لإصدارات مواد عرض JavaScript وCSS. من المفترَض أن تظهر لك رموز الاستجابة السريعة المعروضة باستخدام Cache-Control: max-age=31536000، وأن حالة HTTP لكل منها هي 200. بسبب الإعدادات المستخدَمة، لا يتوفّر طلب فعلي على خادم Node.js، وسيؤدي النقر على الإدخال إلى عرض تفاصيل إضافية، بما في ذلك ظهور الاستجابة "(من ذاكرة التخزين المؤقت على القرص)".

حالة استجابة الشبكة 200.

ولا تعتبر القيم الفعلية لعمودي ETag وlast-Modify مهمة جدًا. المهم هو التأكد من إعدادها.

وخلاصة القول

من خلال اتّباع الخطوات الواردة في هذا الدرس التطبيقي حول الترميز، أصبحت الآن على دراية بكيفية ضبط رؤوس استجابة HTTP في خادم ويب يستند إلى Node.js باستخدام Express، من أجل الاستخدام الأمثل لذاكرة التخزين المؤقت HTTP. لديك أيضًا الخطوات التي تحتاج إليها للتأكد من استخدام سلوك التخزين المؤقت المتوقّع من خلال لوحة الشبكة في "أدوات مطوري البرامج" في Chrome.