استخدام Fetch API في JavaScript: التعامل الصحيح مع الاستجابات والأخطاء
تطوير المواقع

استخدام Fetch API في JavaScript: التعامل الصحيح مع الاستجابات والأخطاء

تعلم طلب البيانات من API باستخدام fetch وasync/await، والتحقق من status، ومعالجة JSON والأخطاء بطريقة قابلة للصيانة.

ما الذي تفعله Fetch API؟

تسمح Fetch API بإرسال طلبات HTTP من JavaScript واستقبال نتائجها دون إيقاف بقية الصفحة. ويمكن استخدامها لجلب JSON أو إرسال بيانات إلى خدمة ويب، لكن اكتمال الوعد بنجاح لا يعني أن حالة HTTP نفسها ناجحة؛ لذلك يجب فحص الاستجابة قبل التعامل مع محتواها.

مثال آمن لجلب JSON

async function loadUsers() {
  try {
    const response = await fetch("/api/users");
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }
    const users = await response.json();
    return users;
  } catch (error) {
    console.error("تعذر تحميل المستخدمين:", error);
    throw error;
  }
}
يوضح المثال فصل طلب الشبكة عن التحقق من الحالة وتحويل الجسم إلى JSON.

لماذا نتحقق من response.ok؟

ترفض fetch الوعد عادةً عند تعذر الاتصال أو فشل الطلب على مستوى الشبكة، لكنها لا تعتبر حالات مثل 404 و500 أخطاءً ترفض الوعد تلقائيًا. افحص response.ok أو response.status صراحةً، ثم قرر كيف سيتعامل التطبيق مع الحالة قبل قراءة البيانات.

التعامل مع JSON غير الصالح

ليس مضمونًا أن يحتوي كل رد على JSON صالح؛ فقد تكون الاستجابة فارغة أو يعيد الخادم نصًا مختلفًا عن المتوقع. وقد يفشل response.json() عند التحليل، لذا افصل هذا النوع من الأخطاء عن فشل الشبكة وحالات HTTP، كي تعرض رسالة مناسبة وتسهّل تشخيص السبب.

إلغاء الطلبات الطويلة

استخدم AbortController عندما يتغير البحث بسرعة أو يغادر المستخدم الشاشة. مرّر signal إلى fetch ثم استدعِ abort عند الحاجة. هذا يساعد على منع عرض نتائج قديمة بعد وصول طلب أحدث.

الأمان وCORS

لا تضع مفاتيح سرية في JavaScript المرسل إلى المتصفح. سياسة CORS يحددها الخادم، ولا ينبغي محاولة تجاوزها من جهة العميل. تحقّق أيضًا من البيانات القادمة قبل إدراجها في DOM، واستخدم textContent بدل innerHTML عند عرض نص غير موثوق.

قائمة اختبار قبل النشر

قبل النشر، جرّب المسار الناجح وحالات 404 وأخطاء الخادم وانقطاع الاتصال وJSON غير الصالح وإلغاء الطلب. أظهر حالة تحميل ورسالة مفهومة عند الفشل، وتجنب تسجيل رموز الدخول أو البيانات الشخصية في وحدة التحكم.

الخلاصة

Fetch تصبح أكثر موثوقية عندما تجمع بين async/await وفحص HTTP ومعالجة التحليل والإلغاء. اجعل مسؤولية الطلب واضحة، وتجنب تكرار منطق الأخطاء في كل مكوّن.

مصادر وروابط موثوقة

كلمات مفتاحية:JavaScript FetchFetch APIREST APIHTTP errorsasync await

التعامل مع حالات الشبكة والبيانات

نجاح استدعاء fetch() لا يعني أن استجابة HTTP ناجحة؛ افحص response.ok أو رمز الحالة قبل التعامل مع البيانات. كما ينبغي مراعاة أن الاستجابة قد تكون فارغة أو غير صالحة بصيغة JSON.

async function loadItems() {
  const response = await fetch('/api/items');
  if (!response.ok) {
    throw new Error('تعذر تحميل العناصر');
  }
  return response.json();
}

loadItems()
  .then(items => renderItems(items))
  .catch(() => showMessage('حدث خطأ. حاول مرة أخرى.'));

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

نمط صحيح للتعامل مع الاستجابات

لا يرفض fetch() الوعد تلقائيًا عند استجابة HTTP مثل 404 أو 500؛ افحص response.ok أو response.status قبل تحليل البيانات. وقد يفشل تحليل JSON أيضًا إذا أعاد الخادم جسمًا فارغًا أو نصًا غير صالح، لذلك افصل بين أخطاء الشبكة وحالة HTTP وشكل البيانات.

async function loadItems() {
  const response = await fetch('/api/items');
  if (!response.ok) throw new Error('HTTP ' + response.status);
  const items = await response.json();
  if (!Array.isArray(items)) throw new Error('Unexpected response');
  return items;
}

المسار توضيحي. اعرض للمستخدم رسالة مفهومة وخيار إعادة المحاولة عند الحاجة، ولا تكشف تفاصيل تقنية حساسة. استخدم AbortController لإلغاء الطلبات التي لم تعد مطلوبة.

جدول تشخيص أخطاء Fetch API

استخدام fetch لا يعني أن كل استجابة غير ناجحة سترفض الوعد تلقائيًا. عادةً يرفض fetch عند أخطاء الشبكة أو حالات تمنع الحصول على الاستجابة، بينما قد تعيد استجابة HTTP مثل 404 أو 500 كائن Response عاديًا؛ لذلك ينبغي فحص response.ok أو response.status قبل قراءة البيانات على أنها نجاح.

الحالةما الذي تراجعه؟معالجة مناسبة
فشل الشبكةالاتصال وCORS وعنوان URLرسالة خطأ قابلة للفهم مع خيار إعادة المحاولة
استجابة 404هل المورد موجود والمسار صحيح؟عرض حالة عدم العثور بدل اعتبارها بيانات ناجحة
استجابة 500سجلات الخادم وتوقيت المشكلةالتعامل مع الفشل دون كشف تفاصيل داخلية
JSON غير صالحContent-Type وجسم الاستجابةالتحقق من التنسيق ومعالجة خطأ parsing

خطوات بناء طلب متين

ابدأ بتحديد الطريقة والرؤوس والبيانات المطلوبة، ثم أرسل الطلب. افحص الحالة قبل قراءة الجسم، وتأكد من أن نوع المحتوى يطابق ما تتوقعه. لا تفترض أن كل واجهة API تعيد JSON في كل حالة؛ قد تعيد نصًا أو جسمًا فارغًا عند الحذف أو الخطأ. استخدم try/catch للتعامل مع أخطاء الشبكة وقراءة الجسم، لكن لا تخفِ الخطأ برسالة نجاح عامة.

التعامل مع إعادة المحاولة والمهلة

إعادة المحاولة مناسبة لبعض أخطاء الشبكة المؤقتة، لكنها قد تكرر عملية غير آمنة إذا كانت الطلبات تغيّر حالة الخادم. ميّز بين GET وطلبات الكتابة، واستخدم آليات منع التكرار عند الحاجة. يمكن استخدام AbortController لإلغاء طلب لم يعد مطلوبًا، مثل بحث تتغير قيمته بسرعة، حتى لا تعرض نتيجة قديمة بعد نتيجة أحدث.

الأمان وعقود البيانات

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

راجع دليل MDN لاستخدام Fetch ومرجع AbortController لبناء معالجة أخطاء قابلة للصيانة.

قائمة إنتاج لـFetch API

قبل استخدام fetch في وظيفة يعتمد عليها المستخدم، تحقق من أن الطلب لا يرسل بيانات غير ضرورية وأن الاستجابة لا تُعرض قبل التحقق من حالتها. إذا كان الطلب يغير بيانات على الخادم، فراجع الصلاحيات وحماية الطلبات المتكررة ومعالجة المهلة. لا تضع رمزًا سريًا داخل كود المتصفح ولا تفترض أن CORS وسيلة مصادقة.

حالات يجب تغطيتها

  • استجابة ناجحة بجسم متوقع.
  • استجابة ناجحة بجسم فارغ أو نوع محتوى مختلف.
  • استجابة HTTP غير ناجحة مثل 404 أو 500.
  • فشل شبكة أو انقطاع اتصال.
  • إلغاء الطلب لأن المستخدم غيّر الصفحة أو المدخل.

عرض الخطأ للمستخدم

اعرض رسالة تشرح ما يمكن فعله، مثل إعادة المحاولة، دون إظهار stack trace أو تفاصيل داخلية. احتفظ بالتفاصيل التقنية في سجل مناسب لا يحتوي على بيانات حساسة. إذا كانت النتيجة قديمة بسبب طلب سابق، فلا تستبدل بها نتيجة أحدث.

راجع دليل MDN لاستخدام Fetch ومرجع AbortController.

تصميم معالجة أخطاء Fetch بطريقة قابلة للتشخيص

يتعامل Fetch مع فشل الشبكة على نحو مختلف عن استجابة HTTP غير الناجحة. قد ينجح الوعد ويعيد استجابة بحالة 404 أو 500، لذلك افحص response.ok أو رمز الحالة قبل تحليل المحتوى. أما انقطاع الاتصال أو حظر الطلب أو بعض أخطاء CORS فقد يؤدي إلى رفض الوعد. التمييز بين هذه الحالات يجعل رسالة المستخدم أدق ويساعد المطور على تحديد الطبقة التي تحتاج إلى إصلاح.

تعامل مع نوع المحتوى قبل التحليل

لا تستدعِ response.json() بصورة عمياء إذا كان الخادم قد يعيد HTML أو جسمًا فارغًا عند الخطأ. افحص Content-Type عندما يكون ذلك مناسبًا، وتعامل مع فشل التحليل كحالة منفصلة. تجنب عرض نص استجابة خام للمستخدم، فقد يحتوي على تفاصيل داخلية أو معلومات لا ينبغي كشفها. احتفظ بالتفاصيل التشخيصية في سجل آمن محدود بدل إظهارها في الواجهة.

أدر حالات التحميل والإلغاء

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

اختبر المسارات المختلفة

غطِّ استجابة ناجحة، و404، و500، ومهلة أو انقطاع اتصال، وبيانات غير قابلة للتحليل، وإلغاء متعمد. لا تعتبر كل فشل سببًا لإعادة المحاولة تلقائيًا؛ فإعادة إرسال طلب يغيّر البيانات قد تنتج آثارًا مكررة ما لم تكن العملية مصممة لذلك. استخدم سياسة retry مناسبة للطلبات الآمنة فقط، مع حدود زمنية وتراجع تدريجي عندما يكون ذلك مبررًا.

راجع دليل MDN لاستخدام Fetch ومرجع AbortController. افصل رسالة الخطأ التي يحتاجها المستخدم عن التفاصيل الفنية اللازمة للتشخيص.

قائمة مراجعة لطلبات الشبكة في الواجهة

  • تحقق من رمز HTTP قبل افتراض نجاح العملية.
  • تعامل مع أنواع المحتوى الفعلية ولا تفترض أن كل استجابة JSON.
  • أظهر حالة تحميل ورسالة فشل قابلة للفهم مع إبقاء البيانات الضرورية.
  • امنع تحديث الواجهة بنتيجة طلب قديم إذا بدأ طلب أحدث.
  • استخدم الإلغاء والمهلات وسياسة إعادة المحاولة بما يناسب نوع العملية.

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

راقب طلبات الشبكة دون كشف بيانات حساسة

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

الخلاصة

الخلاصة: افحص response.ok وحالات الشبكة والـHTTP وتنسيق البيانات، واعرض أخطاء مفهومة دون كشف تفاصيل داخلية. اختبر حالات الفشل وإلغاء الطلب كما تختبر النجاح.

الكاتب: عماد الدين لمراني