يوضّح لك هذا الدرس التطبيقي حول الترميز كيفية تغيير عناوين التخزين المؤقت 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
لمعرفة ما إذا كان هناك أي تحديث لملف HTML المخزّن مؤقتًا. تشير استجابة HTTP 304 إلى عدم توفّر HTML معدَّل.
الصفّان التاليان مخصّصان لأصول JavaScript وCSS التي تتضمّن إصدارات. يجب أن تظهر هذه الصفحات مع الرمز Cache-Control: max-age=31536000
، وأن تكون حالة HTTP لكل صفحة هي 200
. بسبب الإعدادات المستخدَمة، لا يتم إرسال أي طلب فعلي إلى خادم Node.js، وسيؤدي النقر على الإدخال إلى عرض تفاصيل إضافية، بما في ذلك أنّ الردّ جاء "(من ذاكرة التخزين المؤقت على القرص)".
لا تهمّ القيم الفعلية لعمودَي ETag وLast-Modified كثيرًا. الأمر المهم هو التأكّد من ضبطها.
ملخّص
بعد إكمال الخطوات الواردة في هذا الدرس التطبيقي حول الترميز، ستكون على دراية بكيفية إعداد عناوين استجابة HTTP في خادم ويب يستند إلى Node.js باستخدام Express، وذلك لتحقيق الاستخدام الأمثل لذاكرة التخزين المؤقت HTTP. تتوفّر أيضًا الخطوات اللازمة للتأكّد من استخدام سلوك التخزين المؤقت المتوقّع، وذلك من خلال لوحة "الشبكة" في "أدوات مطوّري البرامج في Chrome".