JSON Toolkit

كيف تصلح أخطاء تحليل JSON: فحص Unexpected token خطوة بخطوة

الخلاصة: حوّل أخطاء JSON.parse إلى سطر وحرف، ثم استبعد ستة أسباب: الفواصل الزائدة، وعلامات الاقتباس المفردة، والتعليقات، وأحرف التحكم، وBOM، والاقتطاع.

مبتدئقراءة نحو 12 دقيقةنُشر في 2026-10-30حُدِّث في 2026-11-01
غلاف تشخيص أخطاء تحليل JSON

الخلاصة: عند خطأ تحليل، اقرأ السطر والعمود المُبلَّغ عنهما لتجد أول حرف غير صالح، ثم قرر ما إذا كانت علامة اقتباس ناقصة أو فاصلة ناقصة أو فاصلة زائدة أو BOM أو اقتطاعًا — ولا تُعِد قراءة المستند كله من البداية.

رسالة الخطأ لا تخبرك أبدًا "ما الخطأ"؛ بل تخبرك فقط "أين توقف المحلل عن المضي". وهذا الموضعان ليسا المكان نفسه في كثير من الأحيان.

1. أولًا، حوّل الخطأ إلى إحداثيات

ينتج JSON المكسور نفسه أخطاءً مختلفة تمامًا في لغات مختلفة، لكن جميعها يمكن تحويلها إلى "أي سطر، أي حرف":

البيئة الخطأ النموذجي كيف تقرأه
Browser / Node Unexpected token } in JSON at position 42 position إزاحة حرف تبدأ من 0، وليست رقم سطر
Node 20+ Unexpected non-whitespace character after JSON at position 42 يعني أن الجزء الأول صالح والمحتوى الزائد يبدأ بعد 42
Java Jackson Unexpected character ('}' (code 125)): was expecting ... at [Source: (String)..."..." ; line: 3, column: 1] يعطي السطر والعمود مباشرةً، وهو الأكثر فائدة بين الجميع
Python json.decoder.JSONDecodeError: Expecting ',' delimiter: line 3 column 1 (char 42) char هو الإزاحة؛ والسطر والعمود هما المهمان
Go invalid character '}' looking for beginning of object key string يعطي الحرف فقط، فعليك التتبع وتحديد موقعه بنفسك

بمجرد حصولك على الموضع، الصق JSON في محلل JSON على الإنترنت؛ فتضع الأداة المؤشر عند موضع الخطأ وتُبرز رقم السطر والعمود — هذه الخطوة توفر 90% من التخمين البصري على الأحرف.

2. الأخطاء الستة عالية التكرار

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

{
  "name": "json",
  "version": 1,
}

هناك فاصلة زائدة قبل }. لا تسمح مواصفة JSON بالفواصل الزائدة، بينما تسمح بها حرفيات كائنات JavaScript، لذا فإن الإعدادات المنسوخة من الشيفرة هي الأكثر عرضة لحملها. الإصلاح: احذف الفاصلة الأخيرة؛ وإن كانت هذه البيانات تعيش في ملف JS من الأصل، فانتقل إلى تحويل JSON5 بدلًا من فرضها في JSON.

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

{ 'name': 'json' }
{ name: "json" }

لا يجوز أن تستخدم نصوص JSON إلا علامات الاقتباس المزدوجة، ويجب أن تكون المفاتيح نصوصًا بين علامتي اقتباس مزدوجتين أيضًا. وهاذان صياغة مخففة في JSON5 / JavaScript، لا JSON. ويجب كتابة علامة الاقتباس المزدوجة داخل النص كـ \"، والشرطة المائلة العكسية كـ \\.

3. التعليقات

{
  // Timeout in milliseconds
  "timeout": 3000
}

لا يوجد في صياغة RFC 8259 موضع للتعليقات. إما أن تحذف التعليقات، أو تحفظ الملف كـ .jsonc / .json5 وتستخدم محللًا يدعم التعليقات. ولمقارنة "خطط التعليقات" المختلفة راجع كيفية كتابة التعليقات في JSON.

4. الأسطر الجديدة الخام وأحرف التحكم داخل النصوص

{"sql": "SELECT *
FROM t"}

لا يجوز أن تحتوي نصوص JSON على أسطر تغذية خام أو tabs أو أحرف التحكم U+0000–U+001F؛ ويجب كتابتها كـ \n و\t و\u0009. وعند حشو نص متعدد الأسطر في JSON، اهرّبه مرة في محرر أولًا، أو عالجه بشكل موحد بـ ضغط JSON وهروبه.

5. ترويسة BOM

يحمل UTF-8 المحفوظ بـ Windows Notepad البايتات الثلاثة EF BB BF. ويُبلِّغ JSON.parse بالرسالة Unexpected token عندما يصادف BOM، والعين لا تراه إطلاقًا. كيف تعرف: افحص ترويسة الملف بالنظام الست عشري، أو انسخ المحتوى إلى أداة على الإنترنت وانظر هل يظهر الحرف الأول كـ . الإصلاح: احفظ بصيغة "UTF-8 without BOM".

6. محتوى مقتطع

سجل طبع أول 4096 حرفًا فقط، أو استجابة API قطعتها بوابة، أو تنزيل منقطع — السمة المميزة لهذه الفئة هي "الخطأ في النهاية" وعدم تطابق عدد الأقواس. عُدّ الأقواس أولًا: فإن لم تتطابق إغلاقات { و[ فالاقتطاع هو السبب لا الخطأ النحوي. وفي هذه الحالة لا تصلح شيئًا — اذهب واحصل على البيانات الكاملة.

3. إنذاران كاذبان يتعلقان بالنص الصيني والهروب

يتحول النص الصيني إلى \u4e2d\u6587: هذا هروب JSON صالح، لا نص مشوّه. وبعد التحليل تُستعاد القيمة إلى الصينية؛ ولا تظهر صيغة \u إلا عندما تنظر إلى النص الخام مباشرة. وعندما تحتاج إلى عرضه للناس، أخرجه فقط بـ أداة التنسيق؛ ولا يهمك استراتيجية الهروب إلا عندما يجب أن يصمد النص الصيني في URL أو في سجل.

يتحول النص الصيني إلى نص مشوّه مثل 涓枃: هذه مشكلة ترميز لا مشكلة JSON. وهي تحدث عندما تُفك بايتات UTF-8 بترميز GBK، فينتج هذا النمط المنتظم من "ثلاثة أحرف تنوب عن حرف صيني واحد". تحقق من Content-Type: application/json; charset=utf-8 في ترويسة الاستجابة، ومن تحديد encoding='utf-8' صراحةً عند قراءة الملف.

4. سير عمل إصلاح في خمس دقائق

  1. الصقه في الأداة: استخدم المحلل على الإنترنت أولًا لتحديد الخطأ الأول، وأصلح واحدًا في كل مرة؛
  2. تحقق بعد كل إصلاح: أعد التحليل بعد كل تغيير، حتى لا تُخفي الأخطاء الجديدة الخطأ القديم عند إصلاح عدة مواضع دفعة واحدة؛
  3. اضغطه مرة: انزع المسافات البيضاء بـ Minify وأعد التحليل؛ فهذا يفرّق بين "أخطاء بنيوية" و"مشكلات مسافات أو أسطر جديدة"؛
  4. قارن البنية: إن ظهر خطأ فجأة بعد تغيير، فاستخدم JSON diff مقابل النسخة السابقة؛ والفرق عادةً هو تلك الفاصلة الواحدة؛
  5. التحقق على مستوى الحقول: إن نجحت الصياغة لكن رفضتها طبقة الأعمال (حقل ناقص، نوع خاطئ)، فهذا يندرج تحت تحقق JSON Schema، وليس مشكلة صياغة.

5. لماذا يُحلَّل أحد مقطعين "متطابقين" ولا يُحلَّل الآخر

السبب الأكثر شيوعًا هو أحرف غير مرئية: الفاصلة بعرض كامل ,، وعلامات الاقتباس بعرض كامل “”، والمسافة غير الفاصلة U+00A0، والمسافة بعرض صفري U+200B. وعلى الشاشة يكاد لا يمكن تمييزها عن نظيراتها نصف العرض، لكن أيا منها ليس جزءًا من صياغة JSON.

هناك طريقة واحدة للتمييز: انسخ المحتوى حول الحرف المذنب وافحص نقاط الشيفرة بايتًا بايتًا. وتشغيل ما يلي في وحدة تحكم المتصفح يسرد كل حرف غير ASCII وخارج نطاقات النص الصيني:

[...text].filter((ch) => {
  const code = ch.codePointAt(0);
  return code > 127 && !(code >= 0x4e00 && code <= 0x9fff);
});

إن ظهر في الناتج 0x201c (علامة اقتباس مزدوجة يسرى) أو 0xff0c (فاصلة بعرض كامل) أو 0x00a0، فهي الجاني.

6. الوقاية أرخص من الإصلاح

  • شغّل فحص تحليل على ملفات الإعدادات قبل الإرسال؛ ويكفي سطر واحد في CI: node -e "JSON.parse(require('fs').readFileSync('config.json','utf8'))"؛
  • ولّد استجابات API بمكتبة تسلسل؛ ولا تلصق نصوصًا يدويًا أبدًا — فالنصوص المبنية يدويًا هي المصدر الوحيد للفواصل الزائدة وعلامات الاقتباس الناقصة؛
  • عند تسجيل JSON، استدعِ JSON.stringify أولًا بدلًا من إدراجه في قالب نصي، حتى لا يُؤخذ حمولة نصف مكتوبة على أنها رسالة كاملة.

FAQ

كيف أحدد موضع خطأ نحوي في JSON بسرعة؟

خُذ الموضع أو السطر/العمود الذي يبلّغ عنه المحلل؛ فالموضع إزاحة حرف تبدأ من 0 وليس رقم سطر، بينما يبلّغ Java Jackson وPython عن السطر والعمود مباشرة. الصق JSON في محلل JSON على الإنترنت فتضع الأداة المؤشر عند موضع الخطأ وتُبرز السطر والعمود. وإن كان الخطأ في البداية، فافحص ترويسة الملف بحثًا عن BOM وابحث عن أحرف غير مرئية.

لماذا تكون الإعدادات المنسوخة من الشيفرة عرضة جدًا لفاصلة زائدة؟

تحظر مواصفة JSON الفواصل الزائدة بينما تسمح بها حرفيات كائنات JavaScript، لذا تجلب الإعدادات المنسوخة من شيفرة JS فاصلة بسهولة. والإصلاح هو ببساطة حذف الفاصلة الأخيرة؛ وإن كانت البيانات تنتمي إلى ملف JS أصلًا فإن الانتقال إلى تحويل JSON5 أنسب من فرضها في JSON.

هل أستطيع تحليل ملف إعدادات يحتوي تعليقات بوصفه JSON عاديًا؟

لا — لا يوجد في صياغة RFC 8259 موضع للتعليقات، لذا يثير تحليله المباشر خطأً. إما أن تحذف التعليقات، أو تحفظ الملف كـ .jsonc / .json5 وتستخدم محللًا يدعم التعليقات. ولمقارنة خطط التعليقات راجع كيفية كتابة التعليقات في JSON.