304 Not Modified: الطلبات الشرطية وكفاءة الزحف
304 Not Modified يخبر العميل أن نسخته المخزّنة ما زالت حديثة، فيرسل الخادم الترويسات فقط دون جسم.
304 Not Modified هو طريقة الخادم ليقول: «لديك آخر نسخة بالفعل». لا يظهر إلا ردًا على طلب شرطي (conditional request)، وليس له جسم، وهذا يوفر عرض النطاق للمتصفحات وشبكات CDN والزواحف على السواء.
كيف تعمل الطلبات الشرطية
يعرّف RFC 9110، القسم 15.4.5 الرمز 304 بأنه الرد على طلب GET أو HEAD شرطي كان سيعيد 200 OK لو لم يتحقق الشرط. ويبني العميل هذا الشرط من مُحققات (validators) أرسلها الخادم سابقًا:
ETag: يرسل العميل لاحقًاIf-None-Matchبهذه القيمة.Last-Modified: يرسل العميل لاحقًاIf-Modified-Sinceبهذا التاريخ.
فإذا بقي المحقق مطابقًا، يعيد الخادم 304 بالترويسات فقط. ويجب أن يتضمن الرد الترويسات التي كان سيحملها الرد 200 من بين ETag وDate وVary وContent-Location وCache-Control وExpires. وعندما يحمل الطلب الشرطين معًا، تكون الأولوية لـ If-None-Match ويُتجاهل If-Modified-Since.
لماذا يهم 304 للسيو
تقول وثائق Google عن رموز حالة HTTP إن 304 يخبر مرحلة الفهرسة بأن المحتوى هو نفسه كما في آخر زحف. وقد تعيد Google حساب إشارات الرابط، لكن الرمز لا يؤثر في الفهرسة بخلاف ذلك. بعبارة أخرى، هو آمن وفعّال. وتدعم زواحف Google التحقق بكل من ETag وLast-Modified، وقد أوصت Google باستخدام ETag لأنه أقل عرضة للخطأ من الاثنين.
الفائدة هي كفاءة الزحف. فإرسال 304 لا يكلّف خادمك تقريبًا شيئًا، ولذلك يستطيع Googlebot فحص روابط أكثر بالموارد نفسها. وفي المواقع الكبيرة التي فيها صفحات كثيرة لم تتغير، يعني ذلك اكتشافًا أسرع للصفحات التي تغيّرت فعلًا.
أين يسوء الأمر مع 304
- مُحققات قديمة. إذا حُسب ETag من شيء لا يتغير عندما يتغير المحتوى، مثل إصدار القالب، يواصل الخادم الرد بـ 304 بعد أن تحدّث الصفحة، وتحتفظ ذواكر التخزين المؤقت بالنسخة القديمة.
- عدم تحديث Last-Modified عندما تغيّر التعليقات أو الأسعار أو الروابط ذات الصلة محتوى HTML.
- إرسال 304 لطلبات غير شرطية. طبقة تخزين مؤقت معطوبة ترسل 304 لعميل لم يطلب بشكل شرطي فتتركه بلا شيء يعرضه.
- تغيّر ETag بسبب الضغط. بعض الخوادم تعدّل ETag أو تضعّفه عند ضغط الردود، فلا يطابق
If-None-Matchالتالي أبدًا. - اختلاف ETag بين الخوادم خلف موزّع أحمال، فنادرًا ما تتطابق الطلبات المتتابعة.
كيف تفعّله وتختبره
يضيف Apache وNginx المحققات إلى الملفات الثابتة تلقائيًا في العادة (etag on; هو الإعداد الافتراضي في Nginx). أما HTML الديناميكي فكثيرًا ما تنقصه؛ ويمكن لذاكرة تخزين الصفحات أو CDN أو middleware الردود الشرطية في إطار العمل أن تضيفها. وهذه نسخة مبسطة في PHP:
$etag = '"' . md5($html) . '"';
header('ETag: ' . $etag);
if (trim($_SERVER['HTTP_IF_NONE_MATCH'] ?? '') === $etag) {
http_response_code(304);
exit;
}
echo $html;
تأكد أولًا أن الصفحة ترسل ترويسة ETag أو Last-Modified بواسطة أداة فحص ترويسات HTTP. ثم أعد إرسال المحقق بـ curl وتوقّع الرد 304:
curl -I https://www.example.com/guide/ \
-H 'If-None-Match: "6a1f-5e2c"'
HTTP/2 304
etag: "6a1f-5e2c"
cache-control: public, max-age=600
date: Fri, 30 Oct 2026 08:00:00 GMT
كما يراجع اختبار سرعة الصفحة ترويسات التخزين المؤقت لديك.
الأسئلة الشائعة
هل يضر الرد 304 Not Modified بالسيو؟
لا. تقول Google إن 304 يخبرها فقط أن المحتوى لم يتغير منذ آخر زحف. فهو يوفر الموارد ويمكن أن يجعل زحف المواقع الكبيرة أكثر كفاءة.
هل يرسل Googlebot الترويستين If-None-Match وIf-Modified-Since؟
تدعم زواحف Google الطلبات الشرطية باستخدام ETag مع If-None-Match، وLast-Modified مع If-Modified-Since. وكون جلب معيّن شرطيًا يعتمد على امتلاك Google نسخة سابقة من الرابط.
لماذا تعرض أدوات المطوّر 304 بينما تعرض أداة الفحص 200؟
كان لدى متصفحك نسخة مخزّنة فأرسل المحققات، فرد الخادم بـ 304. أما أداة الفحص فتطلب الصفحة من جديد بلا محققات فتحصل على 200. والاثنان صحيحان.