كل من عمل مع واجهات برمجية صادف رسالة خطأ واحدة لا توضّح موضع المشكلة: «Unexpected token». المشكلة أن JSON صارم جداً، والملفات في المشاريع الحقيقية يكتبها أناس وأدوات مختلفة. في هذا الدليل نأخذ الأخطاء الأكثر تكراراً، ونفسر سبب كل خطأ، وكيف تصل إلى موضعه الصحيح بدل التخمين.

الفاصلة الزائدة

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

broken.jsonjson
{
  "name": "Sara",
  "roles": ["admin", "editor",],
}

السبب واضح: بعد قيمة "editor" توجد فاصلة، ثم يأتي القوس الختامي مباشرة. عند التحليل ستحصل على شيء كهذا:

المخرجاتtext
SyntaxError: Unexpected token ']'
  "roles": ["admin", "editor",]
                                 ^

الاقتباس المفرد والقيم غير المحمية

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

broken.jsonjson
{
  'name': 'Sara',
  active: true
}
  • السطر الأول يستخدم علامة اقتباس مفردة للمفتاح والقيمة، وصحيح أن يكون مزدوجاً.
  • الحقل active منطقي، ولذلك لا يحتاج علامات اقتباس حوله.
  • القيم المنطقية true و false و null هي الاستثناء الوحيد الذي لا يحتاج اقتباساً.

التعليقات غير مسموح بها

لا يوجد تعليق بسطر واحد ولا تعليق متعدد الأسطر داخل JSON. هذا يختلف عن ملفات إعداد مثل tsconfig.json التي تسمح بالتعليقات، لكنه ينطبق على أي ملف .json عادي وعلى استجابات الـ API:

broken.jsonjson
{
  // اسم المستخدم
  "username": "sara"
}

إذا كان لديك ملف يحتوي تعليقات، فالحل العملي هو إزالتها قبل الإرسال.Albديل الأنظف هو نقل التعليق إلى حقل يحمله:

valid.jsonjson
{
  "_comment": "اسم المستخدم",
  "username": "sara"
}

قيم غير قياسية: NaN و Infinity و undefined

هذه القيم موجودة في JavaScript لكنها غير موجودة في معيار JSON. محاولة وضعها داخل ملف JSON تنتج إما خطأ مفاجئاً أو تحويلاً صامتاً:

ما الذي يحدثjavascript
const data = { score: NaN, count: Infinity, extra: undefined };

// عند التحويل إلى JSON:
// { "score": null, "count": null }  <- تحويل إلى null
// الحقل extra يختفي تماماً
  • القيمة NaN تتحول إلى null عند التحويل. إذا كان null غير مقبول في نظامك، استخدم قيمة بديلة مثل صفر أو سلسلة نصية.
  • القيمة undefined تُحذف من الناتج تلقائياً، فإذا كان الحقل إجبارياً فسيختفي بصمت دون أي رسالة خطأ.
  • القيمة Infinity في المصفوفات تتحول إلى null، وقد يظهر ذلك كأرقام فارغة في لوحة التحليلات.

أرقام بصيغة غير صحيحة

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

broken.jsonjson
{
  "zip": 01234,
  "price": 10,50,
  "ratio": 1.
}
  • الرمز البريدي 01234 يبدأ بصفر، اجعله سلسلة نصية entre قوسين: "01234".
  • السعر يجب أن يستخدم النقطة العشرية لا الفاصلة: 10.50.
  • الرقم 1. ينتهي بنقطة، ويجب حذف النقطة أو إضافة أرقام بعدها.
الرسالةالسبب الأرجحالحل
Unexpected token }فاصلة زائدة أو قوس زائداحذف الفاصلة قبل القوس الختامي
Unexpected token 'اقتباس مفرد بدل المزدوجاستبدل العلامة المفردة بالمزدوجة
Unexpected token Nقيمة NaN أو Infinityاستبدلها بقيمة قياسية
Unexpected non-whitespaceتعليق أو نص خارج البنيةاحذف التعليقات
Unexpected end of inputقوس أو علامة اقتباس ناقصةتحقق من إغلاق كل الأقواس

الخطأ الذي لا علاقة له بصيغة JSON

أحياناً لا تكون رسالة الخطأ عن JSON إطلاقاً، بل عن أن ما وصلك ليس JSON أصلاً. الأسباب الشائعة:

  1. المحتوى فارغ تماماً، إما لأن الطلب أُلغي أو انتهت مهلته.
  2. صفحة خطأ بصيغة HTML من الخادم، مثل خطأ 500، فالحل في الخادم لا في البيانات.
  3. البيانات ملفوفة في كائن خارجي فأنت تحاول تحليل الكود المصدري بدل المصفوفة.
  4. ترويسة نوع المحتوى لا تطابق المحتوى الفعلي.
التشخيصjavascript
const res = await fetch("/api/data");
console.log(res.status, res.headers.get("content-type"));
const text = await res.text();
console.log(text.slice(0, 120)); // افحص النص قبل التحليل
const data = JSON.parse(text);