Skip to content
العودة إلى المدوّنة
دروس تعليمية

أكواد حالة HTTP: مرجع شامل من 1xx إلى 5xx بأمثلة

مرجع شامل لأكواد حالة HTTP من 1xx إلى 5xx بأمثلة عملية، الفروق بين 401 و403 و301 و302، وتأثير SEO. اطّلع على المرجع الآن.

14 دقائق للقراءة

أكواد حالة HTTP: مرجع من 1xx إلى 5xx بأمثلة

تفتح أدوات المطوّر فترى تبويب الشبكة نصفه أحمر. نقطة النهاية تُرجع 502 في الإنتاج و200 محلياً، وزميل لك على Slack يسألك للتو: «هل ينبغي أن يكون هذا 401 أم 403؟». أكواد حالة HTTP ثلاثة أرقام موزّعة على خمس فئات، لكنّ الاختيار الخاطئ يُسرّب المعلومات، ويكسر تحسين محركات البحث (SEO)، ويحوّل مناوبات الطوارئ إلى كابوس.

هذا الدليل مرجع لأكواد حالة HTTP للمطورين. ستجد فيه جدولاً مرجعياً سريعاً لكل كود تصادفه فعلياً في الإنتاج، ومصفوفات قرار للأزواج التي يخلط الناس بينها (301 vs 302 و401 vs 403 و404 vs 410 و502 vs 504)، وقسم أدوات يوضح كيفية فحص أكواد الحالة من curl وfetch ومكتبة Python requests. كل كود مذكور أدناه مستند إلى RFC 9110، وهو المعيار الحالي لدلالات HTTP، وإلى سجل أكواد حالة HTTP في IANA.

مرجع سريع: أكواد حالة HTTP في جدول واحد

هذه الأكواد التي ستلتقي بها في الإنتاج، مجمَّعة حسب الفئة. أضف الجدول إلى مفضّلتك، وبقية المقال تشرح الأكواد الأكثر إشكالاً.

الكودالاسممتى ستراه
100Continueإرسال جسم POST كبير مع Expect: 100-continue
101Switching Protocolsمصافحة WebSocket، الترقية إلى HTTP/2
103Early Hintsالخادم يرسل ترويسات Link قبل الاستجابة الفعلية
200OKالنجاح الافتراضي لـ GET وPUT وPATCH
201CreatedPOST ينشئ مورداً (يُرجع Location)
202Acceptedمهمة غير متزامنة في الطابور، العمل لم يكتمل بعد
204No Contentنجاح DELETE، أو PUT دون جسم استجابة
206Partial Contentطلب نطاق، تخطّي في الفيديو، تنزيل قابل للاستئناف
301Moved Permanentlyالرابط القديم تُقاعَد، محركات البحث تنقل وزن الروابط
302Foundإعادة توجيه مؤقتة، الرابط الأصلي يبقى الرسمي
303See Otherنمط Post/Redirect/Get بعد إرسال نموذج
304Not ModifiedGET مشروط مع تطابق ETag أو If-Modified-Since
307Temporary Redirectمثل 302، لكن مع الحفاظ على المنهج والجسم
308Permanent Redirectمثل 301، لكن مع الحفاظ على المنهج والجسم
400Bad RequestJSON مشوّه، حقل مطلوب مفقود، فشل المخطط
401Unauthorizedلا توجد بيانات اعتماد، أو رمز انتهى صلاحيته
403Forbiddenمستوثَق لكن غير مسموح
404Not Foundالمورد غير موجود (أو تخفيه عمداً)
405Method Not AllowedPOST إلى نقطة نهاية تقبل GET فقط (يجب تضمين Allow)
408Request Timeoutالعميل استغرق وقتاً طويلاً لإرسال الطلب
409Conflictفشل قفل تفاؤلي، مفتاح مكرر
410Goneالمورد حُذف بشكل دائم ولن يعود
415Unsupported Media TypeContent-Type خاطئ، مثلاً XML إلى واجهة JSON
422Unprocessable Contentالبنية صحيحة، لكن الدلالة خاطئة (خطأ تحقّق)
425Too Earlyخطر إعادة تشغيل بيانات مبكرة في TLS 1.3
428Precondition Requiredالخادم يلزمك بـ If-Match لتفادي التحديثات المفقودة
429Too Many Requestsتجاوز حد المعدل (يجب تضمين Retry-After)
451Unavailable for Legal ReasonsDMCA، إزالة GDPR، حظر جغرافي
500Internal Server Errorاستثناء غير معالَج في كودك
501Not Implementedالمنهج أو الميزة غير مدعومين (نادر في REST)
502Bad Gatewayالخادم الأعلى أرجع استجابة غير صالحة
503Service Unavailableوضع صيانة أو إفراط في التحميل
504Gateway Timeoutالخادم الأعلى لم يستجب في الوقت المحدد
507Insufficient StorageWebDAV نفذت لديه المساحة
508Loop Detectedإعادة توجيه لا نهائية أو تكرار في WebDAV
511Network Authentication Requiredبوابة أَسر في فندق أو مطار يطلب تسجيل الدخول

بقية المقال تفكّك كل فئة عبر مصفوفات قرار ومضادّات أنماط وعواقب الاختيار الخاطئ على SEO.

كيف تعمل أكواد حالة HTTP (تشريح الأرقام الثلاثة)

لماذا ثلاثة أرقام؟

أكواد حالة HTTP ثلاثة أرقام عشرية لأن HTTP/0.9 احتاج إشارة بطول ثابت يتفرّع عليها المحلِّل بسرعة، وتتسع في الوقت نفسه لأكواد جديدة. ثلاثة أرقام تمنحك 900 قيمة ممكنة (100–999)، وهذا أكثر بكثير مما تحتاج؛ سجل IANA اليوم يستخدم نحو 60 كوداً فقط.

الرقم الأول يمثل الفئة، والرقمان الثاني والثالث يحدّدان الكود المعيّن داخل تلك الفئة. على العميل الذي لا يتعرّف على 418 أن يتعامل معه بوصفه 4xx عاماً. RFC 9110 §15 ينص على ذلك صراحةً: على العملاء أن يعاملوا الأكواد غير المعروفة كأنها x00 من فئتها.

الفئات الخمس في لمحة

الفئةالمعنىهل الجسم مطلوب؟قابلة للتخزين المؤقت افتراضياً؟
1xxإعلامية، استجابة مؤقتة، المزيد قادملالا
2xxنجاح، الطلب فُهم وقُبلغالباًيعتمد على المنهج
3xxإعادة توجيه، تحتاج إجراء إضافياًاختياري301 و308 نعم؛ 302 و307 لا
4xxخطأ من العميل، خطؤك أنت، صحّح الطلبنعم (مع شرح)عموماً لا
5xxخطأ من الخادم، خطؤنا نحن، قد تنفع إعادة المحاولةنعم (مع شرح)لا

عمود «قابلة للتخزين المؤقت افتراضياً» مهم. شبكات توصيل المحتوى (CDN) والمتصفحات تخزّن 301 و308 بشراهة وإلى الأبد، فاختيار كود إعادة توجيه خاطئ في الإنتاج يصعب التراجع عنه، لأن المستخدمين يحتفظون بإعادة التوجيه مخزَّنة محلياً. سنعود إلى هذه النقطة في قسم SEO.

إذا أردت التعمّق في بنية الـ URL (وهي ما تعمل عليه أكواد إعادة التوجيه)، فإن ترميز وفك ترميز URL: دليل المطورين يأخذك خطوة بخطوة عبر التشفير بالنسبة المئوية وسلاسل الاستعلام وخط الأنابيب على مستوى البايت الذي يقرّر متى يكون الـ URL صالحاً ابتداءً.

1xx — إعلامية (متى ستراها فعلاً)

معظم المطورين يقضون سنوات دون أن يروا 1xx مباشرةً. هذه استجابات مؤقتة، يقول فيها الخادم للعميل: «ما زلت هنا، تابع». أدوات المطوّر في المتصفح تخفيها عادةً، ومعظم مكتبات HTTP تطويها داخل الاستجابة النهائية.

ولكل كود أدناه، يفيدك مرجع MDN لأكواد استجابة HTTP إن أردت رأياً ثانياً في تعريف ما.

100 Continue

العميل يرسل Expect: 100-continue ضمن ترويساته وينتظر قبل بثّ جسم طلب كبير. الخادم يرد بـ 100 Continue إن كان مستعداً لاستلام الجسم، أو بـ 4xx إن كان سيرفض الطلب على أي حال. هذا يوفّر عرض النطاق في الرفعات الكبيرة؛ لا فائدة من إرسال 200 ميغابايت إن كان الخادم سيرفض الطلب بسبب ترويسة مفقودة.

curl -v -H "Expect: 100-continue" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @big-file.bin \
  https://api.example.com/upload

إن لم تجد < HTTP/1.1 100 Continue في خرج الوضع التفصيلي، فالغالب أن عميلك جرّد الترويسة أو أن الخادم لا يدعمها.

101 Switching Protocols

المصافحة التي تحوّل اتصال HTTP إلى اتصال WebSocket أو HTTP/2. العميل يرسل Upgrade: websocket، والخادم يرد بـ 101 Switching Protocols، ومن تلك اللحظة يتكلّم الاتصال بروتوكولاً مختلفاً. ستراها في تبويب الشبكة لأي تطبيق دردشة أو لوحة قيادة حيّة أو أداة تعاون.

103 Early Hints

كود حديث نسبياً (RFC 8297، 2017) يتيح للخادم إرسال ترويسات Link لتلميحات التحميل المسبق قبل أن تجهز الاستجابة الرئيسية. يبدأ المتصفح في جلب CSS وJS بينما يكمل الخادم العَرْض. وحتى 2026، يدعم كل من Cloudflare وFastly وVercel الكود 103 في الإنتاج، وهو البديل الحديث لدفع الخادم في HTTP/2 (الذي أُهمل في Chrome).

HTTP/1.1 103 Early Hints
Link: </styles.css>; rel=preload; as=style
Link: </app.js>; rel=preload; as=script

HTTP/1.1 200 OK
Content-Type: text/html
...

فحص مضادّ النمط. إذا كان عميلك لا يرى أكواد 1xx حين تتوقعها، فالمشكلة عادةً في وكيل عكسي. إصدارات nginx القديمة تجرّد Expect: 100-continue و103 Early Hints. راجع إعدادات الوكيل قبل أن تفترض أن الخادم معطّل.

2xx — نجاح (ما هو أبعد من 200)

إعادة 200 OK لكل شيء أكثر روائح الكود انتشاراً في واجهات REST. عائلة 2xx تحمل معلومات دلالية تجعل العملاء أذكى والذواكر المؤقتة أكفأ.

200 OK

الافتراضي. GET يُرجع المورد، وPUT يُرجع المورد المحدَّث (أو 204)، وPATCH يُرجع المورد بعد الترقيع. إن لم يكن لديك سبب لاستخدام كود أكثر تحديداً، فاستخدم 200.

201 Created

ينبغي لـ POST الذي ينشئ مورداً جديداً أن يُرجع 201 مع ترويسة Location تشير إلى المورد الجديد. هكذا يكتشف عملاء REST الـ URL الرسمي للشيء الذي أنشؤوه.

HTTP/1.1 201 Created
Location: /api/users/42
Content-Type: application/json

{"id": 42, "name": "Ada Lovelace"}

202 Accepted

الخادم قبل الطلب لكنه لم يُنهِ معالجته بعد. استخدمه للأعمال غير المتزامنة، فعلى العميل أن يستفسر دورياً، أو يشترك في webhook، أو يفحص نقطة نهاية للحالة. اقرنه بمعرّف مهمة في الجسم.

204 No Content

نجاح بلا جسم. شائع مع DELETE (المورد ذهب، فما الذي ستعيده؟)، ومع عمليات PUT حيث يعرف العميل سلفاً الحالة الجديدة. لن يغيّر المتصفح الصفحة الحالية إن أرجع نموذج إرسال 204، وهذا مفيد لإجراءات «أطلق وانسَ» في تطبيقات الصفحة الواحدة.

206 Partial Content

تُرجع لطلبات النطاق؛ العميل يطلب البايتات من 1000 إلى 2000 عبر ترويسة Range: bytes=1000-2000، ويرد الخادم بتلك الشريحة فقط. بثّ الفيديو والتنزيلات القابلة للاستئناف ومزامنة الملفات عبر HTTP كلها تعتمد على 206.

قرار: 200 vs 201 vs 204 لـ POST

السيناريوالكودالجسم
POST ينشئ مورداً جديداً201 Createdالمورد الجديد (أو معرّفه فقط) + Location
POST يطلق عملاً غير متزامن، النتيجة لم تجهز202 Acceptedمعرّف المهمة، رابط الاستفسار
POST إجراء بلا مورد (مثل /login)200 OKنتيجة الإجراء (رمز، حالة)
POST ينجح لكن الاستجابة فارغة204 No Content(لا شيء)

إن ترددت بين 200 و201، فاسأل: «هل أنشأ الخادم مورداً يحمل الآن URL خاصاً به؟». نعم؟ فـ 201. لا؟ فـ 200.

3xx — إعادة توجيه (301 vs 302 vs 307 vs 308)

إعادات التوجيه أكثر الفئات سوء استخدام. الفروق بين 301 و302 و307 و308 تتلخّص في ثلاثة أسئلة متعامدة: هل النقل دائم، وهل المنهج محفوظ، وهل الاستجابة قابلة للتخزين المؤقت.

301 Moved Permanently

المورد انتقل ولن يعود. محركات البحث تنقل وزن الروابط إلى الـ URL الجديد. المتصفحات وCDN تخزّن 301 إلى أجل غير مسمى، فلو أعدت توجيه /old إلى /new بـ 301 ثم غيّرت رأيك، سيستمر المستخدمون الذين خزّنوا إعادة التوجيه في الذهاب إلى /new إلى الأبد (أو حتى يمسحوا الذاكرة المؤقتة).

تاريخياً، قد تعيد المتصفحات كتابة منهج الطلب على 301 (POSTGET)، ولهذا أدخل HTTP/1.1 الكود 308 لمعالجة الأمر.

302 Found

إعادة توجيه مؤقتة. الـ URL الأصلي يبقى الرسمي، وعلى محركات البحث أن تواصل فهرسته. استخدمه لتوجيه اختبارات A/B وصفحات الصيانة وتدفقات «سجّل الدخول للمتابعة».

كحال 301، أعادت المتصفحات تاريخياً كتابة POST إلى GET على 302. إن أردت إعادة توجيه POST مع إبقائه POST، فاستخدم 307 بديلاً عنه.

303 See Other

يعيد كتابة المنهج إلى GET دائماً. هذا هو نمط Post/Redirect/Get: النموذج يُرسَل إلى /submit، فيُرجع الخادم 303 مع Location: /thank-you، ويقوم المتصفح بـ GET /thank-you. تحديث صفحة الشكر لا يعيد إرسال النموذج، وهذا ما صُمّم له 303.

304 Not Modified

الاستجابة المشروطة. العميل يرسل If-None-Match: "abc123" (أو If-Modified-Since)، فيفحص الخادم ما إذا تغيّر المورد، فإن لم يتغيّر يُرجع 304 بلا جسم، ويستخدم المتصفح نسخته المخزَّنة. هكذا تحافظ كل شبكة CDN وكل طبقة تخزين مؤقت على سرعة موقعك.

307 Temporary Redirect

كـ 302، لكن يجب ألّا يتغيّر المنهج. POST يبقى POST، والجسم محفوظ. استخدمه حين تريد إعادة توجيه مؤقتة على طلب غير GET.

308 Permanent Redirect

كـ 301، لكن المنهج يجب ألّا يتغيّر. الخيار الحديث الأكثر أماناً لإعادات التوجيه الدائمة على واجهات تقبل POST/PUT.

مصفوفة قرار: أي كود إعادة توجيه؟

دائم (تخزين أبدي)مؤقت (لا تخزّن)
يجوز أن يتغيّر المنهج إلى GET301 Moved Permanently302 Found
يجب أن يبقى المنهج كما هو308 Permanent Redirect307 Temporary Redirect

حالة خاصة: إن أردت تحديداً POSTGET (نمط Post/Redirect/Get)، فاستخدم 303 See Other.

لصفحات HTML مع تنقّل المتصفح، يكون 301 و302 عادةً ملائمَين لأن GET يبقى GET. أما لواجهات API والنماذج، فيُفضَّل 308 و307 لتفادي إعادة كتابة المنهج بشكل مفاجئ.

4xx — أخطاء العميل (اختيار الصحيح منها)

4xx تعني أن العميل ارتكب خطأً ما. كلما أثرَيت مفردات 4xx لديك، صار استخدام واجهتك أسهل؛ يستطيع العملاء التفرّع على الكود بدلاً من تحليل سلاسل أخطاء.

400 Bad Request

خطأ صياغي عام. JSON مشوّه، أو حقل مطلوب مفقود على المستوى البنيوي، أو طلب لا يستطيع الخادم حتى تحليله. إن كان الطلب يُحلَّل لكنه يفشل في التحقق التجاري، ففضّل 422.

401 Unauthorized vs 403 Forbidden

أكثر زوج يُخلط بينه في HTTP. الفرق بسيط متى رأيته:

  • 401 Unauthorized: الطلب يفتقر إلى مصادقة صالحة، والخادم لا يعرف من أنت. إعادة إرسال بيانات الاعتماد (أو تجديد الرمز) قد تحلّ المشكلة. الاستجابة يجب أن تتضمن ترويسة WWW-Authenticate وفق RFC 9110 §15.5.2.
  • 403 Forbidden: الخادم يعرف من أنت ويرفض على أي حال. إعادة إرسال الطلب لن تنفع. تحتاج بيانات اعتماد مختلفة أو صلاحيات مختلفة.
ما تراهالحقيقة
401 مع WWW-Authenticate: Bearerلا رمز، رمز منتهٍ، أو رمز غير صالح
403 بعد تسجيل دخول ناجحمسجَّل لكن المستخدم لا يستطيع الوصول إلى هذا المورد
401 بعد تسجيل دخول ناجحخطأ برمجي — على الأرجح تريد 403

مضادّ نمط: 403 بدلاً من 404. بعض المواقع تُرجع 403 حين يطلب مستخدم غير مصادَق /admin/dashboard، وهذا يسرّب وجود /admin/dashboard. GitHub يحلّ هذا بإرجاع 404 للمستودعات الخاصة التي لست عضواً فيها، فالمورد «غير موجود» من منظورك. هذا اختيار مقصود لإخفاء المعلومات، لا خطأ.

404 Not Found vs 410 Gone

كلاهما يقول «هذا المورد غير موجود هنا». الفرق في الديمومة وفي SEO.

  • 404 Not Found: قد يوجد، وقد لا يوجد، وقد يعود. محركات البحث ستستمر في الفحص.
  • 410 Gone: كان هنا، وأُزيل عمداً، ولن يعود. محركات البحث تُسقطه من الفهرس بسرعة أكبر.

إن حذفت صفحة منتج وأردت إخراجها من فهرس Google الآن، فـ 410 هو الاختيار الصحيح. أما إذا كان الـ URL معطّلاً مؤقتاً فقط، فـ 404 كافٍ.

405 Method Not Allowed

الـ URL موجود لكنه لا يقبل هذا المنهج. الاستجابة يجب أن تتضمن ترويسة Allow تسرد المناهج المدعومة.

HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD, OPTIONS
Content-Type: application/json

{"error": "POST is not allowed on this endpoint"}

نسيان ترويسة Allow هو أكثر انتهاك للعقد شيوعاً في واجهات REST المكتوبة يدوياً.

408 Request Timeout

العميل بدأ إرسال طلب ثم صمت، فاستسلم الخادم. مختلف عن 504 Gateway Timeout الذي يخصّ الخادم الأعلى؛ 408 يقول: «أنت أيها العميل أخذت وقتاً طويلاً».

409 Conflict

الطلب يتعارض مع الحالة الحالية. الاستخدام الأشيع: القفل التفاؤلي. العميل يرسل If-Match: "etag-v3" بينما ETag الحالي للخادم هو "etag-v4"، فيُرفض التحديث بـ 409.

410 Gone

انظر أعلاه: حذف دائم. مفيد لإخراج السجلات المحذوفة منطقياً من فهارس البحث.

415 Unsupported Media Type

العميل أرسل جسماً لا يفهمه الخادم. إرسال XML إلى واجهة تقبل JSON فقط يعطي 415. الاستجابة ينبغي أن تلمّح إلى الأنواع المقبولة.

422 Unprocessable Content

الطلب يُحلَّل بلا مشكلة، لكنه يفشل في التحقق الدلالي. رفع RFC 9110 هذا الكود من WebDAV إلى المعيار الأساسي في 2022. استخدم 422 لأخطاء التحقق:

{
  "error": "validation_failed",
  "details": [
    {"field": "email", "message": "must be a valid email"},
    {"field": "age", "message": "must be at least 13"}
  ]
}

إن لم تستطع واجهتك التمييز بين 400 و422، فالقاعدة العملية: 400 تعني «لا أستطيع حتى تحليل هذا»، و422 تعني «حلّلتُه ولا معنى له».

425 Too Early

يُرسل حين لا يريد الخادم المخاطرة بمعالجة طلب قد يكون إعادة تشغيل لبيانات مبكرة في TLS 1.3. ذو صلة في الغالب بشبكات CDN والوكلاء العكسيين.

428 Precondition Required

الخادم يصرّ على أن ترسل If-Match أو If-Unmodified-Since لتجنب فقدان التحديث. يُستخدم في واجهات التحرير التعاوني.

429 Too Many Requests

تجاوزت حد المعدل. الاستجابة يجب أن تتضمن Retry-After (بالثواني أو كتاريخ HTTP) كي يتسنى للعملاء المؤدّبين التراجع.

HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/json

{"error": "rate_limited", "limit": 100, "window": "1m"}

الرقم إشارة إلى رواية برادبري. لكن حالة الاستخدام ليست خيالية: إزالات DMCA وطلبات «الحق في النسيان» وفق GDPR والحظر الجغرافي على مستوى الدولة، كلها تبرّر 451. ينبغي أن تتضمن الاستجابة ترويسة Link تشير إلى الجهة القانونية الموجِبة للحجب، وفق RFC 7725.

418 I’m a Teapot (البيضة المخفيّة)

نعم، حقيقي. RFC 2324 (مزحة كذبة أبريل 1998)، وأبقاها IETF في السجلات لأن منتجات كثيرة نفّذتها على سبيل المزاح. لا تشحن 418 في واجهة حقيقية؛ معظم الوكلاء العكسيين وموازِنات الحمل سيتعاملون معها بشكل خاطئ.

مصفوفة قرار: أي كود 4xx؟

الموقفالكود
الجسم مشوّه أو غير قابل للتحليل400
لا مصادقة / رمز منتهٍ401
مستوثَق لكن غير مسموح403
الـ URL غير موجود (أو تخفيه)404
الـ URL كان موجوداً، أُزيل عمداً410
منهج HTTP خاطئ405 (مع Allow)
Content-Type خاطئ415
تعارض قفل تفاؤلي409
خطأ تحقّق (يُحلَّل ولا يجتاز التحقق)422
تجاوز حد المعدل429 (مع Retry-After)
محجوب لأسباب قانونية451

5xx — أخطاء الخادم (ما المعطّل فعلاً)

5xx تعني «خطؤنا نحن». مهندسو المناوبة يهتمّون بأي 5xx أيقظهم في الثالثة فجراً، لأن الكود يدلّك على الطبقة التي يجب أن تفحصها أولاً.

500 Internal Server Error

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

501 Not Implemented

الخادم لا يدعم المنهج إطلاقاً. مختلف عن 405 (هذا المنهج غير مسموح لهذا الـ URL501 يقول: «هذا الخادم لا يعرف ما هو PROPFIND أصلاً». نادر في واجهات REST.

502 Bad Gateway

وكيل عكسي أو موازِن حمل تلقّى استجابة غير صالحة من الخادم الأعلى. الخادم الأعلى ردّ، لكن بمحتوى تالف أو بروتوكول خاطئ أو ترويسات مشوّهة أو اتصال انقطع في منتصف الاستجابة. إن رأيت 502 من شبكتك CDN، فالغالب أن الأصل ينهار أو يُرجع أجساماً مقطوعة.

503 Service Unavailable

الخادم يرفض تقديم الطلبات الآن عمداً. استخدمه لنوافذ الصيانة أو لاستجابات الإفراط الرشيقة. ينبغي تضمين Retry-After.

504 Gateway Timeout

الوكيل العكسي انتظر الخادم الأعلى ولم يستجب الأخير في الوقت المحدد. الخادم الأعلى بطيء أو متوقف، وهذا مختلف عن 502 الذي يردّ فيه الخادم الأعلى بمحتوى تالف.

502 vs 504: تشخيص المناوبة

ما تراهأول ما تفحصه
502 Bad Gatewayالخادم الأعلى يردّ ببيانات غير صالحة، افحص سجلات الأصل بحثاً عن انهيارات، استجابات مشوّهة، عدم تطابق بروتوكولات
504 Gateway Timeoutالخادم الأعلى معلَّق، افحص CPU الأصل، استعلامات قاعدة البيانات، استدعاءات API النازلة، وproxy_read_timeout للوكيل

خلط شائع: استعلام قاعدة بيانات يستغرق 60 ثانية سيظهر بصورة 504 إن انتهت مهلة وكيلك عند 30 ثانية، لكنه سيظهر 500 إن انتهت مهلة خادم التطبيق عند 90 ثانية ورفع استثناءً. السبب الجذري واحد، والكود مختلف، وسطر السجل مختلف، فدرّب لوحات قيادتك على إبراز كليهما.

507 Insufficient Storage

خاص بـ WebDAV. القرص ممتلئ على الخادم. إن رأيت هذا من واجهة ليست WebDAV، فأحدهم يحمّل المعنى ما لا يحتمل.

508 Loop Detected

تكرار لا نهائي في عمليات PROPFIND ضمن WebDAV. نادر جداً.

511 Network Authentication Required

كود البوابات الأَسْرية. واي فاي الفندق أو المطار يرسل 511 ليقول لمتصفحك: «عليك تسجيل الدخول إلى البوابة أولاً». وتتضمن الاستجابة Location يشير إلى صفحة البوابة.

مصفوفة استكشاف الأخطاء: أي طبقة تفحص أولاً

الكودالتطبيقالوكيلقاعدة البياناتالشبكة
500نعمربما (خطأ DB غير ملتقط)
502نعم (الخادم الأعلى مشوَّه)ربما (إعادة تعيين TCP)
503نعم (راية صيانة)نعم (رفض حد المعدل)
504نعم (معالج بطيء)نعم (إعداد المهلة)نعم (استعلام بطيء)نعم (DNS، فقد الحزم)

مضادّات أنماط شائعة في أكواد حالة HTTP

الأخطاء الخمسة التالية تفسّر معظم الكود الرديء في مراجعات الواجهات.

1. تغليف الأخطاء بـ 200 OK

HTTP/1.1 200 OK
{"success": false, "error": "user_not_found"}

كل أداة مراقبة وكل CDN وكل ذاكرة مؤقتة تظنّ الآن أن الطلب نجح. منطق إعادة المحاولة يفشل. موازِنات الحمل المتنبّهة لكود الحالة توجّه الترافيك السيئ إلى خوادم خلفية «سليمة». هذا النمط جاء من JSON-RPC وورثه GraphQL؛ GraphQL يفعله لأن النجاحات الجزئية تحتاج إبلاغ أخطاء على مستوى الحقل، وهذا منصف. أما REST فلا عذر له: استخدم 4xx لأخطاء العميل و5xx لأخطاء الخادم، وضع التفاصيل المهيكلة في الجسم.

2. الخلط بين 401 و403

إن لم يكن 401 و403 متّسقَين عندك، فبإمكان المهاجمين تحسّس واجهتك لاكتشاف الموارد الموجودة. ضع سياسة: إما إرجاع 404 لـ «لا يحقّ لك رؤية هذا» (نهج GitHub للمستودعات الخاصة)، أو إرجاع 403 باتساق. عدم الاتساق يسرّب المعلومات.

3. إخفاء 403 خلف 404

أحياناً صحيح، وغالباً خطأ برمجي. إرجاع GitHub لـ 404 للمستودعات الخاصة مقصود، فوجود المستودع نفسه حسّاس. لكن إن أرجعت واجهتك 404 لـ «هذا الحساب موقوف»، فلن يستطيع المستخدمون الشرعيون التمييز بين كتابة اسم المستخدم بشكل خاطئ والإيقاف. وثّق سياستك صراحةً وطبّقها باتساق.

4. استخدام 500 ملاذاً افتراضياً

تجعل الأطر هذا سهلاً، وهنا تكمن المشكلة. كل استثناء غير ملتقط يصبح 500، وأنظمة التنبيه لديك لا تستطيع التمييز بين «قاعدة البيانات معطّلة» و«المستخدم مرّر UUID مشوّهاً». التقط أخطاء التحقق وارفع 400 أو 422. التقط NotFound من ORM وارفع 404. احتفظ بـ 500 للإخفاقات غير المتوقعة فعلاً، وعند رفعه سجّل معرّف طلب لتربط بين الأحداث.

5. سلاسل إعادة توجيه طويلة

كل قفزة تكلّف رحلة ذهاب وإياب. إن كان /old/intermediate/canonical، فهذا يعني عمليتَي بحث DNS إضافيتين ومصافحتَي TCP إضافيتين (في أسوأ الحالات). يخفّض Google أولوية الزحف للسلاسل الأطول من 3 قفزات تحديداً، وتُسقف المتصفحات سلاسل إعادة التوجيه عند نحو 20 لمنع الحلقات. اضغط السلاسل من المصدر: إعدادات CDN أو خريطة إعادة التوجيه في تطبيقك.

أكواد حالة HTTP وSEO

تتعامل محركات البحث مع أكواد الحالة كإشارات موثوقة بشأن الإبقاء على URL أو إسقاطه أو نقله. اختر خطأ، يتحرّك ترتيبك.

301 vs 302 (وزن الروابط)

301 Moved Permanently ينقل PageRank؛ Google يعامل الـ URL الجديد على أنه الوجهة الرسمية لكل الإشارات الموجَّهة إلى الـ URL القديم. 302 Found لا ينقل وزن الروابط (أو ينقله ببطء، حسب استدلالات Google). إن أعدت تسمية URL إلى الأبد، فاستخدم 301. إن أعدت توجيه ضيف إلى /login، فاستخدم 302.

404 vs 410 vs Soft 404

Google يميّز بين ثلاث حالات «مفقود»:

  • 404 Not Found: يعيد Google الفحص دورياً ويُبقي الـ URL في الفهرس مدّةً.
  • 410 Gone: يُسقط Google الـ URL أسرع، غالباً ضمن دورة زحف واحدة.
  • Soft 404: مصطلح Google لصفحة تُرجع 200 OK لكنها تعرض رسالة «غير موجود». يكتشف Google هذا من أنماط المحتوى ويعامله كـ 404 على أي حال، لكنك أهدرت طلب زحف وربما خفّفت محتواك الحقيقي.

إن كنت تنظّف فهرساً قديماً، فأرجع 410 حقيقية للروابط التي أُزيلت بشكل دائم.

5xx وميزانية الزحف

زاحف Google يقلّل من معدّله حين يُرجع موقع 5xx باستمرار. تقرير «إحصاءات الزحف» في Search Console يُظهر هذا؛ ارتفاع مستمر في أخطاء 5xx قد يخفض ميزانية زحفك أياماً، ما يعني أن الصفحات الجديدة تأخذ وقتاً أطول حتى تُفهرس. عامِل معدلات 5xx مقياساً سيوياً، لا مقياس موثوقية فحسب.

200 OK في حقيقتها معطّلة

إعادة 200 OK مع صفحة خطأ (مضادّ نمط soft-404) أسوأ سيناريو لـ SEO. يفهرس Google رسالة الخطأ، ويصنّفها على لا شيء، ثم يكتشف الصفحة المعطّلة ببطء. أرجع دائماً كود الحالة الصحيح من الخادم، حتى لو عرض تطبيقك أحادي الصفحة واجهة خطأ ودودة.

كيف تفحص أكواد حالة HTTP (الأدوات)

لا يمكنك إصلاح ما لا تراه. ينبغي لكل مطوِّر يعمل بانتظام أن يتقن اثنتين على الأقل من هذه الأدوات.

لوحة الشبكة في أدوات المطوّر بالمتصفح

كلٌّ من Chrome وFirefox وSafari يعرض عمود Status في تبويب الشبكة. انقر بالزر الأيمن على ترويسة العمود لإضافة Status Text إن لم يكن ظاهراً. حيل مفيدة:

  • Preserve log: الإبقاء على الإدخالات عبر التنقّلات لرؤية سلسلة إعادة التوجيه كاملة.
  • التصفية بالحالة: اكتب status-code:5xx (في Chrome) لرؤية أخطاء الخادم فقط.
  • Replay XHR: انقر بالزر الأيمن على أي طلب ← Replay XHR لإعادة تشغيله دون تحديث الصفحة.

لإعادات التوجيه، وسّع الطلب لرؤية كل قفزة وكود الحالة عند كل خطوة.

curl (الأداة الموسوعية)

curl يُظهر كل شيء. ثلاثة أنماط تحلّ 90% من تصحيح الأخطاء:

# Just the status code
curl -o /dev/null -s -w "%{http_code}\n" https://api.example.com/users/1

# Headers only (HEAD request, follow redirects)
curl -I -L https://example.com

# Full verbose with request and response headers
curl -v https://api.example.com/users/1

حين تُنشئ URL اختبارية تحوي رموزاً خاصة في سلاسل الاستعلام، استخدم --data-urlencode لتدع curl يتولى الترميز عنك، أو الصق الـ URL في أداة ترميز وفك ترميز URL للتحقق من البايتات التي ستذهب فعلاً على السلك.

# curl encodes the query value for you
curl -G "https://api.example.com/search" \
  --data-urlencode "q=hello world & friends"

# Sends: GET /search?q=hello%20world%20%26%20friends

JavaScript fetch

الخاصية Response.status تحمل الكود الصحيح. Response.ok تساوي true لأي 2xx.

const res = await fetch('https://api.example.com/users/1');

console.log(res.status);      // 200
console.log(res.statusText);  // "OK"
console.log(res.ok);          // true

if (!res.ok) {
  if (res.status === 401) {
    // refresh token and retry
  } else if (res.status === 429) {
    const retryAfter = Number(res.headers.get('Retry-After')) || 1;
    await new Promise(r => setTimeout(r, retryAfter * 1000));
  } else if (res.status >= 500) {
    throw new Error(`Server error: ${res.status}`);
  }
}

في axios، يعيش المنطق نفسه داخل المعترِضات:

import axios from 'axios';

axios.interceptors.response.use(
  response => response,
  error => {
    const status = error.response?.status;
    if (status === 401) {
      // redirect to login
    }
    return Promise.reject(error);
  }
);

Python requests

import requests

r = requests.get('https://api.example.com/users/1')

print(r.status_code)  # 200
print(r.reason)       # 'OK'

# Raises requests.exceptions.HTTPError for 4xx/5xx
r.raise_for_status()

# Manual handling
if r.status_code == 429:
    retry_after = int(r.headers.get('Retry-After', '1'))
    time.sleep(retry_after)
elif 500 <= r.status_code < 600:
    raise RuntimeError(f'Server error: {r.status_code}')

raise_for_status() هو الاصطلاح في Python لـ «أفشل بصوت عالٍ على 4xx/5xx». استخدمه في السكربتات حين تريد استثناءات على الأخطاء بدلاً من التفرّع على status_code.

Postman وBruno

كلتاهما تتيح لك التأكيد على أكواد الحالة داخل سكربت اختبار:

// Postman/Bruno test script
pm.test("Status is 201", () => {
  pm.response.to.have.status(201);
});

pm.test("Has Location header", () => {
  pm.expect(pm.response.headers.get('Location')).to.match(/^\/users\/\d+$/);
});

شغّل هذه على بيئة staging ضمن CI لاكتشاف انتهاكات العقد قبل الإنتاج.

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

ما الفرق بين 401 و403؟

401 Unauthorized يعني أن الخادم لا يعرف من أنت؛ بيانات الاعتماد مفقودة أو منتهية أو غير صالحة. 403 Forbidden يعني أن الخادم يعرف من أنت ويرفض على أي حال. إن كان إرسال بيانات اعتماد مختلفة قد ينفع، فاستخدم 401. إن لم ينفع، فاستخدم 403.

متى أستخدم 301 وليس 302؟

استخدم 301 حين يكون النقل دائماً، فالـ URL القديم لن يعود أبداً، وتريد محركات البحث أن تنقل وزن الروابط إلى الـ URL الجديد. استخدم 302 لإعادات التوجيه المؤقتة حيث يبقى الـ URL الأصلي رسمياً (تدفقات تسجيل الدخول واختبارات A/B وصفحات الصيانة). لواجهات API، فضّل 308 و307 لأنهما يحفظان منهج الطلب.

ماذا يعني خطأ 502 Bad Gateway؟

502 يعني أن وكيلاً عكسياً أو موازِن حمل تلقّى استجابة غير صالحة من الخادم الأعلى. الخادم الأعلى ردّ، لكن بمحتوى تالف أو بروتوكول خاطئ أو ترويسات مشوّهة أو اتصال انقطع. مختلف عن 504 Gateway Timeout الذي يعني أن الخادم الأعلى لم يردّ إطلاقاً. أول ما تفحصه: سجلات خادم الأصل بحثاً عن انهيارات أو استجابات مقطوعة.

ما هو «soft 404»؟

«soft 404» صفحة تُرجع 200 OK لكنها في الواقع تعرض رسالة «غير موجود». يكتشفها Google استدلالياً ويعاملها كـ 404 على أي حال. تهدر ميزانية الزحف وقد تخفّف محتواك الحقيقي. أرجع دائماً أكواد 404 أو 410 حقيقية من الخادم، حتى لو عرض تطبيقك أحادي الصفحة واجهة خطأ ودودة.

متى أستخدم 422 بدلاً من 400؟

استخدم 400 Bad Request حين لا يستطيع الخادم تحليل الطلب أصلاً، مثل JSON مشوّه أو حقول بنيوية مفقودة أو أخطاء صياغية. استخدم 422 Unprocessable Content حين يُحلَّل الطلب بلا مشكلة لكنه يفشل في التحقق التجاري، مثل صياغة بريد إلكتروني خاطئة أو قيمة خارج النطاق أو حقول غير متّسقة دلالياً. القاعدة المختصرة: 400 للصياغة، و422 للدلالة.

كيف أستجيب لـ 429 Too Many Requests؟

اقرأ ترويسة Retry-After (عدد ثوانٍ أو تاريخ HTTP) وتراجَعْ على الأقل بهذا القدر قبل إعادة المحاولة. إن كانت Retry-After مفقودة، فاستخدم تراجعاً أُسّياً مع jitter ابتداءً من نحو ثانية واحدة. لا تعد المحاولة فوراً أبداً؛ هذه هي الطريقة المضمونة لتُحظَر.

هل ما زالت أكواد 1xx الإعلامية مستخدمة في 2026؟

نعم، لكن معظمها غير مرئي لكود التطبيق. 100 Continue و101 Switching Protocols ميزتان أساسيتان في HTTP/1.1. 103 Early Hints يستخدمه بشكل متزايد Cloudflare وFastly وVercel لدفع تلميحات التحميل المسبق قبل الاستجابة الرئيسية، وهو يحسّن Largest Contentful Paint بشكل ملحوظ. معظم مكتبات HTTP تطوي 1xx داخل الاستجابة النهائية، فلا تراها عادةً إلا في أدوات المطوّر أو في curl -v.

هل 418 «I’m a teapot» كود حالة حقيقي؟

نعم. RFC 2324 كانت مزحة كذبة أبريل من 1998، لكن منتجات كثيرة طبّقتها فأبقاها IETF في السجلات في RFC 7168. لا تشحن 418 في الإنتاج؛ كثير من الوكلاء العكسيين وموازِنات الحمل لا تتعامل معه بشكل صحيح، وهو لا يخدم غرضاً حقيقياً خارج المزحة.

مقالات ذات صلة

عرض جميع المقالات