ما هو JSON؟
JSON (اختصار JavaScript Object Notation) هو صيغة نصية خفيفة لتبادل البيانات المنظّمة. يمثّل البيانات ككائنات ومصفوفات متداخلة من القيم، ويمكن للإنسان قراءته، وتستطيع كل لغات البرمجة الشائعة تحليله — ولهذا تُرسل وتستقبل معظم واجهات API على الويب بيانات JSON.
يغطي هذا الدليل الصياغة التي تحتاجها لكتابة JSON صالح، والأخطاء التي تنتج رسائل «Unexpected token»، وكيفية تنسيق JSON والتحقق منه وتحويله في متصفحك، ومتى تكون صيغة أخرى خياراً أفضل.
صياغة JSON: أنواع القيم الست
مستند JSON هو قيمة واحدة. تكون هذه القيمة عادةً كائناً أو مصفوفة، لكن المعيار (RFC 8259) يسمح بأي من الأنواع الست في المستوى الأعلى.
- الكائن (Object) — مجموعة غير مرتبة من أزواج مفتاح/قيمة داخل أقواس معقوفة: {"id": 7, "name": "ليلى"}. يجب أن تكون المفاتيح نصوصاً بين علامتي اقتباس مزدوجتين.
- المصفوفة (Array) — قائمة مرتبة من القيم داخل أقواس مربعة: ["admin", "editor"].
- النص (String) — نص بين علامتي اقتباس مزدوجتين، مع شرطة مائلة عكسية لتهريب علامات الاقتباس والشرطات وأحرف التحكم: "السطر الأول\nالسطر الثاني".
- الرقم (Number) — عدد صحيح أو عشري مع أسّ اختياري: 42 و-3.5 و1.2e10. لا أصفار بادئة، ولا أرقام سداسية عشرية، ولا NaN أو Infinity.
- القيمة المنطقية (Boolean) — القيمتان true وfalse (بأحرف صغيرة).
- null — القيمة الحرفية null وتعني «لا قيمة».
الجزء 1:{ "user": الجزء 1:{ "id": الجزء 4:7, "name": الجزء 3:"Layla", "active": الجزء 5:true }, "roles": الجزء 2:[ الجزء 3:"admin", الجزء 3:"editor" ], "lastLogin": الجزء 6:null, "balance": الجزء 4:1250.75 }
- 1الكائن (Object)أزواج مفتاح/قيمة داخل أقواس معقوفة. الكائن الخارجي هو القيمة الوحيدة في المستوى الأعلى، والكائن
userمتداخل فيه - 2المصفوفة (Array)قائمة مرتبة من القيم داخل أقواس مربعة
- 3النص (String)نص بين علامتي اقتباس مزدوجتين. والمفاتيح مثل
"name"نصوص أيضاً - 4الرقم (Number)عدد صحيح أو عشري مع أسّ اختياري
- 5القيمة المنطقية (Boolean)
trueأوfalseبأحرف صغيرة - 6
nullالقيمة الحرفيةnull، وتعني «لا قيمة»
مثال هذا القسم، بقيمة واحدة في كل سطر؛ ولم تتغير أي قيمة.
النسخة النصية
{
"user": { "id": 7, "name": "Layla", "active": true },
"roles": ["admin", "editor"],
"lastLogin": null,
"balance": 1250.75
}القواعد التي تسبب معظم أخطاء JSON
يبدو JSON شبيهاً بـ JavaScript لكنه أكثر صرامة بكثير. تنشأ كل أخطاء «Unexpected token» و«Unexpected end of JSON input» تقريباً من إحدى هذه القواعد.
- المفاتيح والنصوص تستخدم علامات الاقتباس المزدوجة فقط. علامات الاقتباس المفردة '...' غير صالحة.
- لا فواصل زائدة في النهاية: [1, 2, 3,] و{"a": 1,} خطأ.
- لا تعليقات. لا يُسمح بـ // ولا /* */ في أي مكان من المستند.
- يجب اقتباس المفاتيح: {name: "Layla"} هي JavaScript وليست JSON.
- لا يمكن أن تبدأ الأرقام بأصفار (007) أو تنتهي بنقطة عشرية (5.).
- يجب أن يحتوي المستند على قيمة عليا واحدة بالضبط — كائنان متجاوران ليسا JSON صالحاً (هذا ما يُسمى JSON Lines).
- الترميز هو UTF-8. علامة ترتيب البايتات (BOM) في بداية الملف تعطّل كثيراً من المحلّلات.
كيفية تنسيق JSON (Pretty Print)
ترسل واجهات API عادةً JSON مصغّراً — بحذف كل المسافات وفواصل الأسطر — لأنه أصغر حجماً. التنسيق يعيد المسافات البادئة لتظهر البنية بوضوح. الصق النص في أداة تنسيق، واختر مسافتين أو أربع مسافات أو علامة جدولة، وانسخ النتيجة؛ والأداة الجيدة تبلّغ أيضاً عن رقم السطر والعمود الدقيق لأي خطأ في الصياغة، ويمكنها ترتيب مفاتيح الكائنات حتى تسهل مقارنة مستندين.
في الكود، تؤدي JSON.stringify(value, null, 2) في JavaScript وjson.dumps(value, indent=2) في Python وjq . file.json في سطر الأوامر المهمة نفسها.
كيفية التحقق من صحة JSON
للتحقق مستويان. التحقق من الصياغة يتأكد من أن النص JSON سليم البنية — كل قوس مغلق وكل قاعدة أعلاه محترمة. أما التحقق من المخطط (Schema) فيذهب أبعد ويفحص البنية مقابل JSON Schema: أي المفاتيح مطلوبة، وما نوع كل قيمة، والنطاقات والأنماط المسموحة.
استخدم التحقق من الصياغة أثناء تصحيح حمولة لا يمكن تحليلها، والتحقق من المخطط عندما تملك عقد API وتريد اكتشاف الاستجابات التي تنحرف عنه.
جرّبها: مدقّق JSON جرّبها: مدقّق JSON Schema جرّبها: مولّد JSON Schema
JSON مقابل XML مقابل YAML
حلّ JSON محل XML كصيغة الويب الافتراضية لأنه أصغر حجماً، ويتطابق مباشرة مع بنى البيانات في معظم اللغات، ولا يحتاج إلى مخطط ليكون مفيداً. ويبقى XML شائعاً في الأنظمة المؤسسية وSOAP، ويدعم السمات ومساحات الأسماء والتعليقات التي يفتقر إليها JSON.
أما YAML فهو مجموعة شاملة لـ JSON صُممت ليكتبها البشر — ملفات الإعداد، وخطوط CI، وملفات Kubernetes. يسمح بالتعليقات ويحذف معظم علامات الترقيم، لكن حساسيته للمسافات تجعله خياراً سيئاً للتبادل بين الآلات. القاعدة العملية: JSON لواجهات API والتخزين، وYAML للإعدادات، وXML عندما يفرضه النظام.
جرّبها: محوّل JSON إلى YAML جرّبها: محوّل JSON إلى XML جرّبها: محوّل XML إلى JSON جرّبها: منسّق YAML جرّبها: منسّق XML جرّبها: مدقّق XML
تحويل JSON إلى CSV وSQL وصيغ أخرى
تتحول مصفوفات JSON المسطّحة من الكائنات إلى CSV بسهولة: يصبح كل كائن صفاً وكل مفتاح عموداً. أما الكائنات المتداخلة فتحتاج إلى تسطيح أولاً (يصبح user.address.city عموداً باسم user.address.city). وتنطبق البنية نفسها على جمل SQL INSERT، وهي أسرع طريقة لتحميل بيانات API في قاعدة بيانات للتحليل.
جرّبها: محوّل JSON إلى CSV جرّبها: محوّل CSV إلى JSON جرّبها: محوّل JSON إلى SQL جرّبها: تسطيح / إلغاء تسطيح JSON
التعامل مع مستندات JSON الكبيرة
عارض الشجرة هو الطريقة العملية لقراءة مستند بآلاف الأسطر: اطوِ ما لا تحتاجه، ووسّع فرعاً واحداً في كل مرة، وانسخ مسار JSONPath لأي قيمة. ولإيجاد قيم محددة أو استخراجها برمجياً، تحدد تعابير JSONPath مثل $.users[?(@.active)].email العقد التي تريدها بالضبط.
جرّبها: عارض شجرة JSON جرّبها: مختبِر JSON Path جرّبها: مقارنة JSON
الأسئلة الشائعة
هل JSON لغة برمجة؟
لا. JSON صيغة بيانات — طريقة لكتابة القيم المنظّمة كنص. لا يحتوي على متغيرات أو دوال أو منطق. اشتُق من صياغة الكائنات في JavaScript لكنه مستقل عن أي لغة.
ما امتداد ملفات JSON؟
الامتداد .json ونوع MIME هو application/json. أما ملفات JSON Lines (قيمة JSON واحدة في كل سطر) فتستخدم .jsonl أو .ndjson.
هل يمكن أن يحتوي JSON على تعليقات؟
JSON القياسي لا يمكنه ذلك. تقبل بعض الأدوات لهجة مخففة (JSONC وJSON5) تسمح بالتعليقات والفواصل الزائدة، لكن واجهات API ومعظم المحلّلات ترفضها.
لماذا يفشل JSON الخاص بي برسالة «Unexpected token»؟
صادف المحلّل حرفاً لم يتوقعه — غالباً فاصلة زائدة، أو نص بعلامات اقتباس مفردة، أو مفتاح غير مقتبس، أو تعليق. تعرض أداة التحقق رقم السطر والعمود بدقة.
هل من الآمن لصق JSON في أداة أونلاين؟
فقط إذا كانت الأداة تعالجه محلياً. تعمل أدوات JSON في متقن بالكامل داخل متصفحك ولا ترفع ما تلصقه أبداً، فتبقى استجابات API التي تحتوي على رموز أو بيانات شخصية على جهازك.
ما الفرق بين JSON وكائن JavaScript؟
كائن JavaScript يعيش في الذاكرة ويمكنه حمل دوال وundefined وتواريخ ومراجع؛ أما JSON فهو تسلسل نصي بستة أنواع قيم فقط. JSON.parse تحوّل النص إلى كائن، وJSON.stringify تفعل العكس.
المراجع
- RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Formatقواعد JSON: الكائنات والمصفوفات والنصوص والأرقام والقيم الثلاث الثابتة، وUTF-8 كترميز للتبادل.
- ECMA-404: The JSON Data Interchange Syntaxصياغة JSON كمعيار من Ecma، متوافقة مع RFC 8259.
- Introducing JSONالوصف الأصلي المختصر لـ JSON مع مخططاته النحوية.
- JSON Schema Specificationالمفردات المستخدمة لوصف بنية مستندات JSON والتحقق منها (الأنواع والحقول المطلوبة والصيغ).
تمرين عملي
أصلح ملف بيانات طلب معطوباً وافحص الاستجابة مقابل العقد
تختبر واجهة API الخاصة بالطلبات في متجر بقالة إلكتروني (مثال خيالي). يفشل اختبار API مؤتمت قبل أن يرسل أي طلب، لأن مشغّل الاختبارات لا يستطيع تحليل جسم الطلب، وهو ملف بيانات الاختبار (fixture) order-request.json الذي كتبه أحد زملائك يدوياً. يعرض الجزء A من المادة هذا الملف، وأرقام الأسطر على اليسار ليست جزءاً منه.
بعد إصلاح الملف يُنشئ الاختبار الطلب، فيعيد GET /api/v1/orders/ORD-77815 على بيئة Staging الاستجابة الواردة في الجزء C، وهي تُحلَّل دون أي خطأ. افحصها حقلاً حقلاً مقابل مقتطف العقد في الجزء B، وحدّد لكل انحراف هل يكشفه التحقق من الصياغة أم التحقق من المخطط (Schema) أم لا يكشفه أيٌّ منهما. اعمل بالورقة والقلم أولاً، ثم أكّد نتائجك بأدوات «مدقّق JSON» و«عارض شجرة JSON» و«مختبِر JSON Path».
الجزء A - الملف order-request.json، وهو جسم الطلب في الاختبار الفاشل
(أرقام الأسطر على اليسار ليست جزءاً من الملف)
1 {
2 // checkout regression: customer with a saved address
3 "customerId": "CUS-1042",
4 "currency": 'SAR',
5 items: [
6 { "sku": "MLK-1L", "quantity": 2, "unitPrice": 6.50 },
7 { "sku": "RCE-5KG", "quantity": 01, "unitPrice": 42. },
8 ],
9 "giftWrap": False,
10 "couponCode": null,
11 "deliveryNote": "Leave it at the gate marked "B"",
12 }
الجزء B - مقتطف من عقد API: جسم استجابة GET /api/v1/orders/{orderId}
(كل الحقول أدناه مطلوبة؛ لكل حقل: الاسم، ثم النوع، ثم القاعدة)
orderId string مثال: "ORD-77815"
status string إحدى القيم "pending" أو "paid" أو "shipped"
أو "delivered" أو "cancelled"
customer.id string مثال: "CUS-1042"
customer.phone string رقم جوال سعودي: "05" يليها 8 أرقام
items array of objects عنصر واحد على الأقل
items[].sku string رمز المنتج المطلوب
items[].quantity integer 1 فأكثر
items[].unitPrice number بالريال، بمنزلتين عشريتين على الأكثر
total number بالريال، بمنزلتين عشريتين على الأكثر؛
وهو مجموع quantity x unitPrice لكل العناصر
giftWrap boolean
couponCode string or null null عند عدم استخدام قسيمة
deliveredAt string or null تاريخ ووقت؛ null حتى يُسلَّم الطلب
الجزء C - بيئة Staging: GET /api/v1/orders/ORD-77815
200 OK, Content-Type: application/json
{
"orderId": "ORD-77815",
"status": "Paid",
"customer": { "id": "CUS-1042", "phone": 501234567 },
"items": [
{ "sku": "MLK-1L", "quantity": "2", "unitPrice": 6.5 },
{ "sku": "RCE-5KG", "quantity": 0, "unitPrice": 42 }
],
"total": 55,
"giftWrap": "false",
"couponCode": null
}- الجزء A: اقرأ الملف سطراً سطراً مقابل قواعد الصياغة في الدليل. لكل خطأ اكتب رقم السطر، والقاعدة التي يخالفها، والنص بعد التصحيح. وسجّل الأسطر الصالحة كما هي.
- الصق الملف الأصلي، دون أرقام الأسطر، في «مدقّق JSON». لا تُصلح إلا الخطأ الواقع في السطر والعمود اللذين يبلّغ عنهما، ثم تحقق مجدداً، وكرّر ذلك حتى يصبح المستند صالحاً. عُدّ الجولات وقارنها بقائمتك.
- الجزء C: اكتب نوع كل قيمة في الاستجابة بحسب أنواع JSON (يعرضها «عارض شجرة JSON»)، وكل مفتاح يطلبه العقد وهو غائب.
- قارن كل حقل بالجزء B: النوع، والقيم المسموحة، والنطاق، والوجود. صنّف كل حقل صحيحاً أو انحرافاً، واذكر مستوى التحقق الذي يكشفه.
- في «مختبِر JSON Path» اكتب تعبيراً واحداً يعيد كمية كل عنصر، واقرأ عمود «النوع». ثم أعد حساب الإجمالي من الطلب المصحَّح ومن عناصر الاستجابة: ما الذي تكشفه المقارنة ولا يستطيع أي مخطط أن يكشفه؟
إظهار الإجابة النموذجية
في الجزء A تسعة أخطاء صياغة. السطر 2: تعليق، وJSON لا يقبل التعليقات. السطر 4: 'SAR' بعلامتي اقتباس مفردتين؛ اكتب "SAR". السطر 5: المفتاح items غير مقتبس؛ اكتب "items". وفي السطر 7 ثلاثة أخطاء: 01 يبدأ بصفر بادئ (اكتب 1)، و42. ينتهي بنقطة عشرية (اكتب 42 أو 42.00)، والفاصلة بعد آخر عنصر في المصفوفة يجب حذفها. السطر 9: False تُكتب بأحرف صغيرة false. وفي السطر 11 خطآن: علامتا الاقتباس المزدوجتان الداخليتان تُنهيان النص قبل أوانه، فهرّبهما بشرطة مائلة عكسية "Leave it at the gate marked \"B\""، والفاصلة بعد آخر عضو في الكائن يجب حذفها.
الأسطر 1 و3 و6 و8 و10 و12 صالحة. فـ6.50 رقم سليم (الأصفار بعد النقطة العشرية مسموحة)، وnull قيمة صالحة، والفاصلة خطأ فقط بعد العنصر الأخير، لذا فالفاصلة في نهاية السطر 6 سليمة. احذف التعليق بدلاً من تحويله إلى مفتاح مثل "_comment": فالملف هو جسم الطلب نفسه، وأي مفتاح إضافي يُرسَل إلى الواجهة أيضاً. ضع الملاحظة في اسم الاختبار أو وصفه.
يحتاج المدقّق إلى تسع جولات، جولة لكل خطأ بترتيب القائمة أعلاه، لأن المحلّل يتوقف عند أول خطأ يصادفه. اعتمد على السطر والعمود، فهما الموضع الذي توقف عنده المحلّل؛ أما التلميح فتخمين مبنيّ على النص المحيط بذلك الموضع، فراجعه مقابل القواعد. وبعد حذف سطر التعليق تنتقل أرقام الأسطر التالية كلها سطراً واحداً إلى الأعلى. وكثيراً ما يُبلَّغ عن الفاصلتين الزائدتين عند القوس المغلق في السطر التالي، حيث يلاحظهما المحلّل. إذن فالخطأ الواحد المُبلَّغ عنه لا يعني أبداً أن في المستند خطأً واحداً: اقرأ المستند كله مقابل القواعد أولاً، واستخدم المدقّق للتأكيد. ولاحظ أيضاً أن الاختبار الفاشل لم يقل شيئاً عن الواجهة: فالعيب كان في مواد الاختبار (Testware)، فتُصلح ملف البيانات ولا تسجّل عيباً على الواجهة.
الجزء C، الأنواع: orderId وstatus وcustomer.id نصوص (string)؛ وcustomer.phone رقم (number)؛ وitems مصفوفة من كائنين، وقيمتا sku فيهما نصّان؛ وquantity نص ("2") في العنصر الأول ورقم (0) في الثاني؛ وقيمتا unitPrice وtotal أرقام؛ وgiftWrap نص؛ وcouponCode قيمته null. أما deliveredAt فغائب.
الصحيح: orderId وcustomer.id وitems (مصفوفة من كائنين) وقيمتا sku وقيمتا unitPrice وcouponCode، ونوع total وصيغته (أما قيمته فتُفحص أدناه). الرقم في JSON قيمة لا صيغة عرض: 6.5 و6.50 رقم واحد، و42 رقم صالح، فعرض «6.50 ريال» مهمة الشاشة. والقيمة null مسموحة في couponCode وتعني أنه لم تُستخدم أي قسيمة.
الانحرافات، ويكشفها كلها التحقق من المخطط ولا يكشف أياً منها التحقق من الصياغة، لأن الاستجابة JSON صالح: (1) status قيمته "Paid"؛ والنصوص تُقارن حرفاً بحرف، فالعميل الذي يتحقق من "paid" لا يرى طلباً مدفوعاً (القيم المسموحة، أي enum). (2) customer.phone هو الرقم 501234567؛ والرقم في JSON لا يبدأ بصفر بادئ، فرقم الجوال المرسَل رقماً يفقد صفره دائماً (النوع string والنمط pattern). (3) items[0].quantity هو النص "2"؛ وفي JavaScript يعطي "2" + 1 النتيجة "21"، فالسلة التي تضيف قطعة أخرى تعرض 21 (النوع integer). (4) items[1].quantity قيمته 0، وهي أقل من الحد الأدنى 1 (minimum). (5) giftWrap هو النص "false"؛ وكل نص غير فارغ يُعامَل معاملة القيمة الصادقة (truthy) في JavaScript، فالشرط if (order.giftWrap) يعامل الطلب على أنه يطلب تغليف هدية (النوع boolean). (6) deliveredAt غائب؛ والمفتاح الغائب ليس null، فنتيجة order.deliveredAt === null هي false لأن القيمة undefined (required).
التعبير $.items[*].quantity يعيد "2" بالنوع string و0 بالنوع number، فيظهر انحرافا الكمية في استعلام واحد، وعلى المسار نفسه يضع الاختبار المؤتمت تأكيداته (Assertions). ويكتب عمود «النوع» number لا integer: ففي JSON نوع رقمي واحد، والعدد الصحيح (integer) قاعدة من العقد، ولها في JSON Schema النوع integer. ويشير «محلّل استجابات API» إلى بعض الانحرافات دون أي عقد (الكمية المرسلة نصاً وبنوع مختلف في كل عنصر، وgiftWrap المرسل نصاً)، لكنه لا يستطيع أن يعرف أن تهجئة الحالة أو رقم الجوال أو المفتاح الغائب أو الكمية الصفرية خطأ؛ فالعقد وحده يخبرك بذلك.
ما لا يكشفه أيّ من المستويين: الطلب المصحَّح طلب 2 × 6.50 + 1 × 42.00 = 55.00 ريال، وtotal قيمته 55، وهذا متطابق. لكن مجموع عناصر الاستجابة 2 × 6.5 + 0 × 42 = 13، فهي تخالف قاعدة العقد بأن total هو مجموعها، والمقارنة بالطلب تبيّن أن الخطأ في كمية RCE-5KG لا في الإجمالي. المخطط يفحص كل قيمة وحدها، ولا يستطيع فحص مجموع يمتد عبر الحقول ولا مقارنة الاستجابة بما طُلب؛ ولو أعاد الخادم الكمية 3 لنجحت كل قواعد المخطط. هذا يحتاج إلى مرجع اختبار (Test oracle)، أي مصدر للنتيجة المتوقعة، وهو هنا الطلب: احسب منه القيم المتوقعة وقارنها في تأكيد. وأبلغ عن كل انحراف بمسار الحقل والقيمة المتوقعة والقيمة الفعلية، مثل: «items[0].quantity: المتوقع عدد صحيح من 1 فأكثر، والفعلي النص "2"»، وأرفق الطلب والاستجابة.
تقدّمك في هذا الموضوع
سجّل الدخول لتتابع تقدّمك
علّم الموضوعات مكتملة، وتابع من حيث توقفت، وافتح امتحانات التخصص.
جزء من مسار تعلم ضمان الجودة
قبل هذا الموضوع
الموضوعات التالية
الأدوات المذكورة في هذا الدليل
تنسيق JSON وتجميله والتحقق من صحته فوراً في متصفحك مع مسافة بادئة قابلة للتخصيص.
التحقق من صحة صياغة JSON مع تحديد مواقع الأخطاء بدقة واقتراحات مفيدة للإصلاح.
استكشاف JSON كشجرة قابلة للطي مع المسارات والأنواع وعدد القيم.
تصغير JSON بإزالة المسافات البيضاء لتقليل حجم الحمولة.
مقارنة مستندي JSON دلالياً وإبراز القيم المضافة والمحذوفة والمتغيرة.
تحويل مصفوفة من كائنات JSON إلى CSV مع تسطيح المفاتيح المتداخلة.
تحويل JSON إلى YAML نظيف وسهل القراءة.
التحقق من مستند JSON مقابل مخطط JSON Schema (الكلمات المفتاحية الأساسية في draft-07 / 2019-09 / 2020-12).