Last-Modified — الجوهر، الآلية وتهيئة رأس تاريخ التعديل

المؤلف: IT Sectr نُشر: 2026-03-09 وقت القراءة: 9 دق

Last-Modified هو رأس استجابة HTTP يشير إلى تاريخ ووقت آخر تعديل للمورد على الخادم، مما يسمح للعميل بتنفيذ طلبات شرطية عبر If-Modified-Since. إذا لم يتغير المورد منذ التاريخ المحدد، يعيد الخادم 304 Not Modified دون إرسال نص الاستجابة، مما يوفر عرض النطاق بشكل كبير. وفقًا لـ RFC 7232 (IETF, 2014)، تقلل الطلبات الشرطية مع Last-Modified وقت تحميل الصفحات بنسبة 30-60% في الزيارات المتكررة. الرأس مدعوم تلقائيًا من معظم خوادم HTTP والبروكسي.

النقاط الرئيسية

  • Last-Modified — رأس HTTP يحتوي على تاريخ آخر تعديل للمورد للطلبات الشرطية If-Modified-Since
  • 304 Not Modified — استجابة الخادم إذا لم يتغير المورد؛ يستخدم العميل نسخته المخزنة مؤقتًا
  • دقة حتى الثانية — قيد الرأس: التغييرات ضمن ثانية واحدة قد تمر دون اكتشاف
  • العمل المشترك مع ETag — يعيد الخادم كلا الرأسين، ويرسل العميل كلا الطلبين الشرطيين
  • التوليد التلقائي — يضبط Nginx و Apache Last-Modified للملفات الثابتة من نظام الملفات

ما هو Last-Modified؟

Last-Modified هو رأس HTTP ينتمي إلى مجموعة رؤوس الطلبات الشرطية. يضيفه الخادم إلى استجابة GET أو HEAD، مشيرًا إلى تاريخ ووقت آخر تعديل للمورد المطلوب بتنسيق HTTP-date: Last-Modified: Wed, 02 Jul 2025 14:30:00 GMT. يحفظ العميل (المتصفح، تطبيق الجوال، البروكسي) هذا التاريخ مع المورد المخزن مؤقتًا. عند طلب لاحق، يرسل العميل رأس If-Modified-Since بنفس التاريخ، ويقارنه الخادم بوقت التعديل الحالي للمورد.

بروتوكول الطلبات الشرطية مع Last-Modified مُعرَّف في RFC 7232 ومدعوم من جميع خوادم HTTP الحديثة. تنسيق التاريخ منظم بدقة — فقط GMT (Greenwich Mean Time) دون تحديد منطقة زمنية. يجب على الخادم إرجاع التاريخ بثلاثة تنسيقات ممكنة: RFC 1123 (قياسي)، RFC 850 (قديم) أو ANSI C asctime. عمليًا، تستخدم جميع الخوادم تقريبًا تنسيق RFC 1123 بطول ثابت 29 حرفًا.

ينتمي Last-Modified إلى فئة آليات التحقق من التخزين المؤقت: لا يخبر العميل ما إذا كان يمكن تخزين الاستجابة مؤقتًا، ولكنه يوفر أداة للتحقق من صلاحية مورد مخزن مؤقتًا بالفعل. يتم تحديد سياسة التخزين المؤقت بشكل منفصل عبر رأس Cache-Control. وفقًا لدراسة Akamai (2025)، يؤدي التهيئة الصحيحة لـ Last-Modified مع Cache-Control إلى تقليل الحمل على خوادم المصدر بنسبة تصل إلى 70% للمحتوى الثابت.

متى ظهر Last-Modified؟

تم تعريف رأس Last-Modified في HTTP/1.0 (RFC 1945, 1996) وأصبح من أوائل آليات إدارة التخزين المؤقت على الويب. قبل ظهور ETag في HTTP/1.1، كان الطريقة الوحيدة لتنفيذ الطلبات الشرطية. على الرغم من عمره، لا يزال الرأس ذا صلة بفضل بساطته — لا يحتاج الخادم إلى حساب تجزئة للمحتوى، يكفي قراءة الطابع الزمني للملف من نظام الملفات أو حقل updated_at من قاعدة البيانات.

كيف يعمل Last-Modified؟

تتكون الدورة الكاملة من ثلاث مراحل. في الطلب الأول، يعيد الخادم المورد مع رأس Last-Modified وحالة HTTP 200 OK. يخزن العميل الاستجابة مؤقتًا مع التاريخ. في طلب متكرر، يرسل العميل رأس If-Modified-Since مع التاريخ المحفوظ. يقارن الخادم هذا التاريخ مع وقت التعديل الحالي للمورد. إذا لم يتغير المورد — يُرجع 304 Not Modified بجسم فارغ. إذا تغير — 200 OK مع بيانات جديدة و Last-Modified جديد.

http
// الطلب الأول — يعيد الخادم المورد مع تاريخ
HTTP/1.1 200 OK
Content-Type: application/json
Last-Modified: Wed, 02 Jul 2025 14:30:00 GMT

[{"id": 1, "name": "Alice"}]

// الطلب المتكرر — يرسل العميل التاريخ المحفوظ
GET /api/users HTTP/1.1
Host: example.com
If-Modified-Since: Wed, 02 Jul 2025 14:30:00 GMT

// الاستجابة — البيانات لم تتغير
HTTP/1.1 304 Not Modified

لتطبيقات الجوال، Last-Modified مفيد بشكل خاص لمزامنة البيانات. يحفظ التطبيق تاريخ آخر تحديث ناجح ويرسله إلى الخادم في If-Modified-Since. إذا كانت هناك بيانات جديدة أو تغيرت — يعيد الخادم المجموعة الكاملة. إذا لم تكن — 304، ويستخدم التطبيق النسخة المحلية. OkHttp و URLSession يدعمان هذه الآلية تلقائيًا عبر أنظمة التخزين المؤقت المدمجة.

كيف يحدد الخادم التاريخ؟

للملفات الثابتة، يأخذ Nginx و Apache التاريخ من سمات نظام الملفات — mtime (وقت التعديل). للمحتوى الديناميكي، يجب أن يضبط كود الخادم Last-Modified بشكل صريح بناءً على منطق الأعمال: حقل updated_at من قاعدة البيانات، تاريخ آخر commit في Git، الطابع الزمني لقطعة البناء. إذا لم يتم ضبط Last-Modified بشكل صريح، قد لا يرسل الخادم الرأس على الإطلاق، ولن يتمكن العميل من تنفيذ طلبات شرطية حسب التاريخ.

Last-Modified مقابل ETag

يؤدي Last-Modified و ETag مهمة مماثلة — السماح للعميل بالتحقق من صلاحية التخزين المؤقت — لكن لديهما اختلافات جوهرية. يستخدم Last-Modified طابعًا زمنيًا، بينما يستخدم ETag معرف إصدار فريد. لكل نهج سيناريوهاته الخاصة حيث يكون أكثر فعالية، وتوصي مواصفات HTTP باستخدام كلا الرأسين معًا.

المعيارLast-ModifiedETag
الجوهرتاريخ آخر تعديلمعرف إصدار فريد
الدقةحتى الثانيةحتى البت (تجزئة)
تعقيد التطبيقمنخفض — تلقائي من نظام الملفاتمتوسط — يتطلب حساب تجزئة
الخوادم المجمعةمشكلة: mtime قد يختلف بين العقدمستقر مع بيانات متطابقة بين العقد
دعم النطاقاتلا يؤثر على طلبات Rangeيتطلب ETag قوي للنطاقات
التوصيةللملفات الثابتة و APIs البسيطةلـ APIs حيث الدقة مهمة

الميزة الرئيسية لـ Last-Modified هي البساطة. لا يحتاج الخادم إلى حساب تجزئة للمحتوى، مما يوفر موارد المعالج في كل طلب. للمشاريع عالية الحركة التي تقدم ملفات ثابتة أو بيانات بطوابع زمنية واضحة، يظل Last-Modified الخيار الأمثل. ETag من ناحية أخرى يوفر دقة مطلقة — تغيير حرف واحد في استجابة JSON سيغير ETag، لكنه قد لا يغير التاريخ (إذا تمت إعادة كتابة الملف بنفس الإصدار).

الاستخدام المشترك

توصي المواصفات بإرجاع كلا الرأسين في وقت واحد. يضمّن الخادم كلا من Last-Modified و ETag في استجابة 200 OK. يرسل العميل كلا الرأسين الشرطيين — If-Modified-Since و If-None-Match. يتحقق الخادم أولاً من ETag (له الأولوية)، ثم Last-Modified. إذا أشار أحدهما على الأقل إلى تغيير — يتم إرجاع الاستجابة الكاملة. وهذا يوفر أقصى مرونة: ETag يضمن الدقة، Last-Modified يوفر فحصًا احتياطيًا للعملاء الذين لا يدعمون ETag.

تهيئة Last-Modified على الخادم

تعتمد تهيئة Last-Modified على نوع الخادم. لـ Nginx و Apache، يتم ضبط Last-Modified تلقائيًا للملفات الثابتة بناءً على mtime. للتطبيقات الديناميكية، يجب ضبط الرأس في كود الخادم. دعنا ننظر إلى التهيئة على المنصات الشائعة.

javascript
// Express.js — ضبط Last-Modified
app.get("/api/users", async (req, res) => {
    const updatedAt = await getLastUpdate()
    const ifModifiedSince = req.get("If-Modified-Since")

    // التحقق من If-Modified-Since
    if (ifModifiedSince && new Date(ifModifiedSince)
        >= updatedAt) {
        return res.status(304).end()
    }

    const users = await getUsers()
    res.set("Last-Modified", updatedAt.toUTCString())
    res.json(users)
})

في مثال Express.js، يحصل الخادم على تاريخ آخر تحديث للبيانات من قاعدة البيانات، ويتحقق من If-Modified-Since من العميل، وإذا كان التخزين المؤقت لا يزال صالحًا — يُرجع 304. إذا تغيرت البيانات — يضبط Last-Modified جديدًا ويعيد الاستجابة الكاملة. toUTCString() تحول التاريخ إلى تنسيق HTTP المطلوب. في الإنتاج، من الجيد تخزين updatedAt مؤقتًا في Redis لتجنب الاستعلام عن قاعدة البيانات في كل طلب.

Nginx: تهيئة Last-Modified

يضبط Nginx تلقائيًا Last-Modified للملفات الثابتة بناءً على وقت آخر تعديل للملف. يمكن تعطيل أو تغيير هذا السلوك باستخدام توجيه etag (تعطيل ETag) أو عبر وحدة ngx_http_headers_module. للطلبات البروكسية إلى الواجهة الخلفية، يتم تمرير Last-Modified من استجابة upstream دون تغيير. مهم: إذا كانت الواجهة الخلفية لا تُرجع Last-Modified، لن يضيفه Nginx تلقائيًا للاستجابات الديناميكية.

القيود والمزالق

لدى Last-Modified عدة قيود معروفة. الرئيسي هو دقة الثانية. إذا تغير المورد مرتين خلال ثانية واحدة، قد يفوت العميل الإصدار الجديد. عمليًا هذا سيناريو نادر، لكن للتحديثات عالية التردد (تدفقات الأسعار، الدردشات) يُوصى بـ ETag. القيد الثاني هو مشكلة التجميع: على خوادم مختلفة قد يكون للملف mtime مختلف بسبب النسخ أو النشر، مما يجعل Last-Modified غير متسق.

القيد الثالث — معالجة If-Modified-Since بدقة الثانية قد تؤدي إلى طلبات غير ضرورية عند الاستقصاء المتكرر للخادم. إذا كان العميل يرسل If-Modified-Since كل 500 مللي ثانية، يعيد الخادم 200 OK في كل مرة لأن التاريخ لم يتغير، لكن المورد قد تم تحديثه بالفعل. الحل هو استخدام مزيج مع ETag: سيلتقط ETag التغيير خلال ثانية، بينما يبقى Last-Modified كخيار احتياطي.

المشكلة الرابعة — Last-Modified لا يفرق بين إصدارات مختلفة من نفس المورد بنفس التاريخ. إذا تمت استعادة ملف من نسخة احتياطية وتطابق mtime الخاص به مع الأصل، لن يلاحظ العميل أن المحتوى تغير. يحل ETag هذه المشكلة: تجزئة المحتوى ستتغير بالتأكيد مع أي تعديل للبيانات، بغض النظر عن الطابع الزمني. للبيانات الحرجة، استخدم دائمًا كلا الرأسين.

  • دقة الثانية — لا يلتقط التغييرات ضمن ثانية واحدة؛ استخدم ETag للتحديثات عالية التردد
  • التجميع — قد يختلف mtime بين الخوادم؛ قم بالمزامنة عبر NTP أو استخدم ETag
  • سباق التوقيت — إذا تغير المورد بعد إرسال If-Modified-Since ولكن قبل التحقق من الخادم
  • سوء تفسير البروكسي — قد تغير بعض البروكسيات Last-Modified عند التخزين المؤقت؛ HTTPS يحل هذه المشكلة

الأسئلة الشائعة

ما تنسيق التاريخ المستخدم في Last-Modified؟

فقط GMT (Greenwich Mean Time) بتنسيق RFC 1123: اليوم من الأسبوع، اليوم، الشهر، السنة، الساعات:الدقائق:الثواني. مثال: Wed, 02 Jul 2025 14:30:00 GMT. المنطقة الزمنية دائمًا GMT، ولا يُسمح بالتنسيقات الأخرى.

هل يمكن أن يكون Last-Modified في المستقبل؟

من الناحية الفنية نعم، لكنه ينتهك RFC 7232. إذا أعاد الخادم تاريخًا مستقبليًا، لن يقوم العملاء بتحديث المورد حتى arrive هذا التاريخ. يعتبر مثل هذا التهيئة خطأ — يجب أن يكون التاريخ في الماضي أو الحاضر.

هل يعمل Last-Modified مع طلبات POST؟

لا، الطلبات الشرطية If-Modified-Since تعمل فقط مع GET و HEAD. لا يتم تخزين طلبات POST مؤقتًا ولا تستخدم التحقق حسب التاريخ. لفحوصات الصلاحية في POST، استخدم ETag أو آليات مخصصة.

كيف يتفاعل Last-Modified مع Cache-Control؟

يحدد Cache-Control سياسة التخزين المؤقت (أقصى وقت تخزين، من يمكنه التخزين)، بينما Last-Modified هو آلية تحقق للتخزين المؤقت منتهي الصلاحية. بعد انتهاء max-age، يرسل العميل If-Modified-Since للتحقق من الصلاحية.

ماذا أفعل إذا لم يتغير Last-Modified عند تحديث البيانات؟

تحقق من أن الخادم يضبط الرأس بالفعل من المصدر الصحيح — قاعدة البيانات، نظام الملفات أو API. للاستجابات الديناميكية، تأكد من استدعاء res.setHeader(“Last-Modified”, ...) صراحةً في كود المعالج.

الخلاصة

  • Last-Modified — رأس HTTP مع تاريخ آخر تعديل للمورد للطلبات الشرطية 304
  • تطبيق بسيط — يعمل تلقائيًا للملفات الثابتة (mtime) ويتطلب الحد الأدنى من الكود لـ APIs
  • دقة الثانية — القيد الرئيسي؛ للتغييرات عالية التردد استخدم ETag
  • ETag أكثر دقة، Last-Modified أبسط — المزيج الأمثل: كلا الرأسين معًا
  • تنسيق تاريخ HTTP — فقط GMT، RFC 1123، طول ثابت 29 حرفًا
  • التجميع — يتطلب مزامنة الوقت (NTP) أو استخدام ETag كآلية رئيسية
  • التوصية — أضف دائمًا Last-Modified لـ APIs وفعّله للملفات الثابتة عبر Nginx/Apache

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا