تخطَّ إلى المحتوى

١١ يوليو ٢٠٢٦

حل خطأ Unexpected token in JSON بالعربي

شارك المقال:

من أكثر أخطاء جافاسكريبت شيوعًا عند التعامل مع أي API:

SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON

أو بصيغته الكلاسيكية:

SyntaxError: Unexpected token < in JSON at position 0

الاسم يوحي بأن مشكلتك في JSON — والحقيقة في 90% من الحالات: ما وصلك ليس JSON أصلًا، وأول حرف منه فضح ذلك.

اقرأ البصمة: الحرف يخبرك بالمشكلة

الرسالة تذكرما وصلك فعليًاالمصدر الغالب
token '<'صفحة HTMLخطأ 404/500، صفحة دخول، رابط خاطئ
Unexpected end of JSON inputنص فارغرد بلا جسم، أو res.json() مرتين
token 'N' (من NaN) أو 'u' (من undefined)قيمة JS غير صالحةخادم يطبع قيمًا خام
حرف عادي بموضع متقدمJSON مكسور فعلًافاصلة زائدة، اقتباس مفرد

خطوة التشخيص الذهبية: شوف النص الخام

قبل أي إصلاح، بدّل التحليل بالطباعة:

// ❌ ما كنت تفعله
const data = await res.json();

// ✅ التشخيص: ماذا وصل فعلًا؟
const raw = await res.text();
console.log(raw.slice(0, 200));   // أول 200 حرف تكشف كل شيء

سترى فورًا: <!DOCTYPE html>... (صفحة خطأ)، أو نصًا فارغًا، أو JSON فيه كسر واضح. وتبويب Network في أدوات المطور يعرض نفس الرد بنقرة — أسرع طريق للحقيقة.

الحلول حسب المصدر

1) وصلتك صفحة HTML — عالج الطلب لا التحليل

الخادم أعاد صفحة خطأ أو تسجيل دخول. افحص الحالة قبل التحليل دائمًا:

const res = await fetch("/api/lessons");
if (!res.ok) {
  // 404؟ 500؟ الرسالة الحقيقية هنا — لا تتركها تنفجر كخطأ JSON مضلل
  throw new Error(`API error ${res.status}: ${await res.text()}`);
}
const data = await res.json();

ثم صحّح السبب: الرابط (typo? مسار نسبي من صفحة فرعية؟)، أو المصادقة، أو راجع حل خطأ CORS إذا كان الرد محجوبًا، وحل خطأ 500 من الخادم إذا كانت الحالة 500.

2) الرد فارغ — Unexpected end of JSON input

  • الخادم يعيد 204 No Content أو جسمًا فارغًا → لا تستدعِ json() أصلًا.
  • فخ شهير: قراءة الجسم مرتين — res.json() بعد res.text() — الجسم يُقرأ مرة واحدة فقط، والثانية تستلم فراغًا.

3) الـ JSON مكسور فعلًا — قواعد صارمة تخالف عادات JS

// ❌ صالح في جافاسكريبت — مكسور في JSON
{
  name: 'أحمد',          // المفاتيح والنصوص: مزدوجة " فقط
  age: 17,               // ← الفاصلة الأخيرة ممنوعة
  // تعليق؟ ممنوع أيضًا
}

// ✅ JSON سليم
{ "name": "أحمد", "age": 17 }

وعلى الخادم: أعد البيانات بأداة التسلسل الرسمية (JSON.stringify / json.dumps) — لا بلصق نصوص يدوي.

قائمة تحقّق سريعة

  • token '<'؟ → الرد HTML: افحص الرابط والحالة وNetwork.
  • افحص res.ok قبل res.json() — في كل fetch تكتبه.
  • end of JSON input؟ → جسم فارغ أو قراءة مزدوجة للجسم.
  • كسر حقيقي؟ → اقتباسات مزدوجة، لا فواصل أخيرة، لا تعليقات.
  • المصدر ملفك أنت؟ مرّره على مدقق JSON قبل اتهام الكود.

الخلاصة

Unexpected token in JSON رسالة مضللة الاسم: نادرًا ما تكون مشكلة JSON، وغالبًا رد خاطئ من الخادم التقطته JSON.parse أول واحد. اطبع النص الخام، افحص الحالة، وستجد المذنب الحقيقي خلال دقيقة.

أكمل عدة التعامل مع البيانات في مسار جافاسكريبت و مسار Node.js، وقارن أخطاء العائلة في جدول أخطاء TypeError و حل Cannot read properties of undefined.

📚 مصادر رسمية للتعمّق: توثيق JavaScript على MDN

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

لماذا يقول position 0 دائمًا تقريبًا؟

لأن أول حرف في النص هو أول ما يفحصه المحلل — وإذا كان الرد صفحة HTML فأول حرف فيها < (من <!DOCTYPE)، وهو حرف لا يبدأ به أي JSON صالح، فينفجر التحليل عند الموضع صفر فورًا. الحرف المذكور في الرسالة هو بصمة نوع المشكلة.

الـ API يعمل في Postman ويفشل في موقعي — لماذا؟

غالبًا الرد لك مختلف: كوكيز جلسة منتهية تعيد صفحة تسجيل دخول HTML، أو مسار نسبي خاطئ في موقعك يصيب صفحة 404، أو مشكلة CORS تعيد ردًا فارغًا. افحص تبويب Network في متصفحك — الرد الحقيقي الذي وصل لموقعك مكتوب هناك حرفيًا.

كيف أتحقق من صحة نص JSON بسرعة؟

الصق النص في محرر أكواد أو أداة تحقق JSON — سيشير للسطر المكسور فورًا. أشهر الكسور اليدوية: فاصلة زائدة بعد آخر عنصر، مفاتيح بلا علامات تنصيص مزدوجة، علامات تنصيص مفردة بدل المزدوجة، وتعليقات — كلها مسموحة في جافاسكريبت وممنوعة في JSON.

اقرأ أيضًا

تصفّح كل المقالات في المدوّنة، أو ابدأ التعلّم من المسارات و خرائط الطريق.