ما هو JSON؟
JSON اختصار لـ JavaScript Object Notation، وهو صيغة بيانات نصّية خفيفة لتبادل المعلومات بين الأنظمة. ابتكره Douglas Crockford في 2001، ومنذ ذلك الحين أصبح اللغة العالمية لـ APIs وإعدادات التطبيقات وقواعد بيانات NoSQL.
رغم اسمه، JSON ليس حكرًا على JavaScript. كل لغات البرمجة الحديثة (Python, Java, PHP, Go, Rust, Swift, Kotlin) تدعمه أصلاً. وحتى بعض قواعد البيانات الكلاسيكية مثل PostgreSQL و MySQL أضافت أنواع JSON كأعمدة أصلية.
القواعد الأساسية لبنية JSON
JSON يتكوّن من 6 أنواع بيانات فقط:
- سلسلة نصية (string): داخل علامتي تنصيص مزدوجتين
"text". لا يُقبل'text'. - رقم (number): صحيح أو عشري
42،3.14،-1.2e5. لا يدعم Infinity أو NaN. - منطقي (boolean):
trueأوfalse(حروف صغيرة فقط). - فارغ (null):
null(حروف صغيرة). - مصفوفة (array): قائمة مرتبة بين
[ ]. - كائن (object): مجموعة أزواج key:value بين
{ }. المفاتيح يجب أن تكون نصوصاً بين علامتَي تنصيص.
قواعد صارمة كثيراً ما يخالفها المطوّرون
- لا يُسمح بفاصلة زائدة بعد آخر عنصر في مصفوفة أو كائن (trailing comma) — على عكس JavaScript.
- لا يُسمح بالتعليقات (لا
//ولا/* */) — استخدم JSON5 إذا احتجت تعليقات. - مفاتيح الكائن يجب أن تكون نصوصاً بين علامتَي تنصيص.
{name: "Ahmad"}غير صالح. - علامتا التنصيص يجب أن تكونا مزدوجتين
"لا مفردتين'.
JSON والمحتوى العربي
JSON يدعم العربية وكل لغات العالم بشكل أصلي عبر UTF-8. الكتابة طبيعية:
{
"اسم": "محمد",
"مدينة": "الرياض",
"هواية": "البرمجة"
}لكن انتبه:
- احفظ ملفات JSON بترميز UTF-8 بدون BOM (Byte Order Mark). BOM يفسد الـ parsing في بعض اللغات.
- قد ترى الأحرف العربية مُرمّزة كـ
\u0645\u062d\u0645\u062f— هذا تمثيل صحيح ومُكافئ لـ "محمد". أكثر برامج تحويل JSON تعيد فك التشفير. - إذا كانت بياناتك تحتوي على رموز emoji أو علامات تشكيل عربية (فتحة، ضمة)، تأكد من استخدام مكتبة JSON parser حديثة.
JSON مقابل XML و YAML
JSON vs XML
- JSON أخف وزناً بنسبة 30-50% من XML لنفس البيانات (لا أقواس مغلقة).
- JSON أسرع في الـ parsing بـ 2-3 أضعاف.
- XML يدعم namespaces و schemas و attributes — قوي للمستندات المعقدة (SOAP, RSS).
- JSON يفوز في APIs الحديثة (REST, GraphQL).
JSON vs YAML
- YAML أكثر قابلية للقراءة (لا أقواس، لا فواصل).
- YAML يدعم تعليقات وعلامات تخصيص (anchors, references).
- JSON أسرع في الـ parsing.
- YAML شائع للإعدادات (Docker Compose, Kubernetes, GitHub Actions). JSON للـ APIs والتطبيقات.
- كل ملف JSON صالح هو ملف YAML صالح (YAML 1.2 superset).
التنسيق والتصغير
التنسيق (Pretty Print)
إضافة مسافات وأسطر جديدة لجعل JSON قابلاً للقراءة البشرية. مفيد للتطوير والوثائق.
// قبل
{"name":"محمد","age":30,"skills":["JS","Go"]}
// بعد (indent: 2)
{
"name": "محمد",
"age": 30,
"skills": ["JS", "Go"]
}التصغير (Minify)
إزالة جميع المسافات والأسطر لتقليل الحجم. ضروري للإرسال عبر الشبكة.
توفير الحجم في المسار للإنتاج (production): استخدم Minify دائماً. الفرق قد يصل إلى 40% من الحجم.
JSON في APIs العربية
أكثر APIs الحكومية والتجارية في العالم العربي تستخدم JSON. أمثلة:
- ZATCA (السعودية): فواتير إلكترونية تُرسل بـ JSON و XML.
- نفاذ (السعودية): تسجيل دخول حكومي عبر OAuth + JSON.
- أبشر: APIs للخدمات الحكومية.
- STC Pay، Apple Pay، Mada: دفعات بـ JSON Web Tokens.
- منصات التجارة الإلكترونية (Salla, Zid): APIs مفتوحة بـ REST + JSON.
قواعد ذهبية في تصميم API بـ JSON
- استخدم snake_case أو camelCase وكن متّسقاً. الخلط بينهما كارثة للمستهلك.
- أعد دائماً نفس البنية حتى في الأخطاء:
{ "success": false, "error": {...} }. - استخدم ISO 8601 للتواريخ:
"2026-05-16T14:30:00Z"— لا تستخدم timestamp رقمي. - لا تُرسل null إن أمكن: اترك المفتاح أو استخدم قيمة افتراضية. null كثيراً ما يُفسد التطبيقات المستهلكة.
- أرسل الأرقام الحسّاسة كنص: أرقام البطاقات، IDs الطويلة (لا فقدان دقة).
- وثّق كل response بمثال JSON حقيقي.
التعديل الجزئي: JSON Patch وJSON Merge Patch
عند تعديل مورد عبر API، إعادة إرسال الكائن كاملاً بـ PUT مكلفة وخطرة: طلبان متزامنان يمحو أحدهما تعديلات الآخر (lost update). معياران رسميّان يحلّان التعديل الجزئي بطريقتين مختلفتين، ومعرفة الفرق بينهما من علامات المطوّر المتمكّن.
JSON Patch (RFC 6902): قائمة عمليّات دقيقة
مصفوفة عمليّات تُنفَّذ بالترتيب: add، remove، replace،move، copy، test. نوع المحتوى في HTTP:application/json-patch+json.
[
{ "op": "test", "path": "/version", "value": 7 },
{ "op": "replace", "path": "/email", "value": "new@example.com" },
{ "op": "remove", "path": "/temp_flag" }
]الميزة الأهمّ: عمليّة test تجعل التعديل شرطيّاً — إن تغيّرت قيمةversion على الخادم قبل وصول طلبك، يفشل الـ Patch كاملاً ويُرفض. هذا يمنحك optimistic locking يمنع سباقات الكتابة دون أقفال قواعد بيانات.
JSON Merge Patch (RFC 7386): أبسط لكن أقلّ دقّة
ترسل جزءاً من الكائن والخادم يدمجه فوق الحالي: القيم الجديدة تستبدل القديمة، وnullيعني «احذف هذا المفتاح». نوع المحتوى: application/merge-patch+json. فخّان يجب حفظهما: (1) لا يمكنك ضبط قيمة على null إطلاقاً لأنّ null محجوز للحذف، (2) المصفوفات تُستبدل كاملة — لا توجد طريقة لإضافة عنصر واحد إلى مصفوفة موجودة.
قاعدة الاختيار: Merge Patch للكائنات البسيطة المسطّحة (تحديث ملفّ تعريف مستخدم)، وJSON Patch عندما تحتاج عمليّات على مصفوفات أو تعديلات شرطيّة أو سجلّ تدقيق يوثّق كلّ تغيير. Kubernetes مثلاً يدعم الصيغتين معاً في kubectl patch.
التحويلات الشائعة
JSON → CSV
مفيد لاستيراد البيانات في Excel أو Google Sheets. يعمل أفضل عندما تكون البيانات مصفوفة من كائنات بنفس البنية. مثال: مصفوفة منتجات من API ← جدول Excel.
JSON → YAML
مفيد لتحويل إعدادات API لإعدادات Kubernetes أو GitHub Actions.
JSON → XML
مطلوب أحياناً للتكامل مع أنظمة قديمة (SOAP, ZATCA UBL 2.1، نظم البنوك التقليدية).
JSON → Query String
مفيد لتحويل JSON معقّد إلى رابط HTTP GET. مثال: filter[category]=tech&sort=desc.
أخطاء كارثية يقع فيها المطوّرون
- فاصلة زائدة:
{"a": 1,}غير صالح في JSON. صالح في JavaScript object literal فقط. - علامات تنصيص مفردة:
{'a': 1}غير صالح. - NaN أو Infinity: JSON لا يدعمها. تجنّبها أو حوّلها إلى null.
- أرقام كبيرة (BigInt): JavaScript يفقد دقة الأرقام الأكبر من 2^53. أرسلها كنصوص:
"id": "1234567890123456789". - دورة كائن (Circular Reference):
JSON.stringify(obj)يرمي خطأ إذا كان لديك كائن يشير لنفسه. استخدم مكتبة مثلflatted. - parsing بيانات غير موثوقة بـ eval: ثغرة أمنية خطيرة. استخدم
JSON.parseدائماً. - عدم التحقق من نتيجة API: فحص
response.okقبلresponse.json(). - تخزين كلمات سر في JSON: اعتقاد أن minify يخفيها. أي شخص يستخدم Postman يراها.
أمان JSON
- JSON Hijacking: ثغرة قديمة. الحل: لا ترجع مصفوفة مباشرة من API، بل غلّفها بكائن:
{ "data": [...] }. - JSON Injection: لا تبني JSON يدوياً بـ string concatenation. استخدم دائماً
JSON.stringify()أو مكتبة موثوقة. - Prototype Pollution: ثغرة حديثة. حدّث Node.js و libraries بانتظام، واحذر من استخدام
Object.assignمع كائنات JSON من مصادر غير موثوقة. - حجم البيانات: ضع حداً أقصى لحجم JSON في API (مثلاً 1MB). JSON parsing لـ 100MB يجمّد السيرفر.
- JSON Web Tokens (JWT): لا تخزّن أسراراً حسّاسة في الـ payload (يمكن decoding بدون مفتاح). JWT يُوقَّع فقط، لا يُشفَّر افتراضياً.
التوقيع الرقمي وJSON Canonicalization (RFC 8785)
مشكلة خفيّة تصطدم بها كلّ خدمة توقّع JSON: {"a":1,"b":2} و{"b":2,"a":1} نفس البيانات منطقيّاً، لكنّ بايتاتهما مختلفة — وأيّ توقيع رقميّ (HMAC، JWS) يُحسب على البايتات لا على المعنى. أعد ترتيب المفاتيح أو أضف مسافة واحدة وسيفشل التحقّق من التوقيع رغم أنّ «البيانات لم تتغيّر».
الحلّ الأوّل (المفضّل): وقّع البايتات الخام
عند التحقّق من توقيع webhook وارد: احسب HMAC على جسم الطلب الخام (raw body bytes) كما وصل، قبل أيّJSON.parse. الخطأ الأكثر شيوعاً: parse ثمّ stringify ثمّ حساب التوقيع — الناتج شبه مؤكّد أن يختلف عن الأصل (ترتيب مفاتيح، مسافات، تمثيل أرقام: 1.0 تصبح1). في Express يعني هذا تركيب raw-body middleware على مسار الـ webhook قبل json parser.
الحلّ الثاني: صيغة قانونيّة موحّدة (RFC 8785)
عندما تُنشئ التوقيع بنفسك من بيانات مبنيّة برمجيّاً ولا توجد «بايتات أصليّة»، يعرّف معيار JSON Canonicalization Scheme صيغة واحدة حتميّة: مفاتيح مرتّبة حسب وحدات UTF-16، بلا مسافات إطلاقاً، تهريب نصوص أدنى، وتمثيل أرقام بقواعد ECMAScript نفسها. نفس البيانات تعطي نفس البايتات دائماً — في أيّ لغة برمجة — فيصبح التوقيع قابلاً للتكرار. مكتبات جاهزة:canonicalize في npm وrfc8785 في Python.
حالات الاستخدام النموذجيّة: توقيع Webhooks الصادرة من نظامك، حساب checksum لكشف تغيّر ملفّات الإعدادات، وسجلّات التدقيق (audit logs) التي يجب أن يعطي فيها الكائن نفسه نفس الـ hash مهما اختلفت اللغة أو المكتبة التي أنتجته.
الأداء والتحقّق بـ JSON Schema
لماذا تحتاج JSON Schema؟
JSON Schema معيار (Draft 2020-12) يصف بنية JSON المتوقّعة: أي حقول إجبارية، أنواعها، حدودها، والعلاقات بينها. بدونه تكتب تحقّق يدوي لكل endpoint — وغياب التحقّق من المدخلات من أكثر أسباب ثغرات APIs شيوعاً وفق تصنيفات OWASP.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["id", "email"],
"properties": {
"id": {"type": "string", "pattern": "^[0-9]+$"},
"email": {"type": "string", "format": "email"},
"age": {"type": "integer", "minimum": 0, "maximum": 150}
}
}مكتبات التحقّق في 2026
- Ajv (Node.js): الأسرع عالمياً — يحول Schema إلى دالة JS محسّنة (compiled validation).
- Zod (TypeScript): Schema و TypeScript types في سطر واحد. المعيار في Next.js/tRPC 2026.
- Pydantic v2 (Python): مصمّم بـ Rust لأداء 5-50x أسرع من v1.
- jsonschema (Python): تطبيق مرجعي للمعيار.
أداء Parsing في 2026
- simdjson: مكتبة C++ تستخدم SIMD instructions لتحليل JSON بسرعة 4 GB/s. استخدمت في Cloudflare و Microsoft Azure.
- JSON.parse() الأصلي: في V8 الحديث (Node.js 22+) تحسّن أداؤه بـ 30% عبر lazy parsing.
- orjson (Python): دوال Rust تتفوّق على json الأصلي بـ 6-10x.
- sonic-cpp/sonic-go (ByteDance): أسرع من encoding/json بـ 3-5x في Go.
متى تستخدم Streaming Parser؟
إذا كان حجم JSON > 100MB أو تعالج بيانات logs حيّة: استخدم streaming (ijson في Python، stream-json في Node) أو تحوّل لـ NDJSON (سطر JSON لكل entry) — المعيار في Big Query و Snowflake و Datadog.
إشكاليّات الترميز العربيّ بعمق
المحتوى العربيّ في JSON ليس بنفس بساطة المحتوى الإنجليزيّ. الأخطاء التي يقع فيها المطوّرون تتكرّر وتُكلّف ساعات من البحث. فيما يلي خمس مشاكل متكرّرة في الأنظمة التي تتعامل مع نصوص عربيّة وحلولها العمليّة.
المشكلة الأولى: BOM (Byte Order Mark) في ملفّات الإعدادات
محرّر النصوص في ويندوز (Notepad) يضيف ثلاث بايتات مخفيّة في بداية الملفّ (EF BB BF) عند الحفظ بـ UTF-8. هذه البايتات لا تظهر للمستخدم لكنّها تُفسد JSON.parse في Node.js وتُنتج خطأ Unexpected token in JSON at position 0. الحلّ: احفظ ملفّاتك بـ «UTF-8 بدون BOM» في VS Code، أو استخدمJSON.parse(text.replace(/^\uFEFF/, '')). ميّزها برؤيتك للحرف الغريب أوّل سطر في hexdump.
المشكلة الثانية: Mojibake (الحروف العربيّة تظهر رموزاً)
عندما ترى Ù…ØÙ…د بدلاً من «محمد»، فالسبب دائماً واحد: ملفّ مكتوب بـ UTF-8 لكنّ القارئ يفسّره بـ Latin-1 أو Windows-1256. هذه المشكلة شائعة في PHP القديم، أو عند تحميل ملفّ JSON من بريد إلكترونيّ، أو في pipelines قراءة CSV ثمّ تحويل لـ JSON. الحلّ الجذريّ: حدّد الترميز صراحةً في كلّ خطوة. في PHP استخدمmb_convert_encoding، في Python encoding='utf-8' صراحةً، وفي HTTP استخدم Content-Type: application/json; charset=utf-8.
المشكلة الثالثة: تشكيل وتنسيق غير مرئي
النصّ العربيّ قد يحتوي على علامات تشكيل (فتحة، ضمّة، شدّة) أو محارف اتّجاه (\u200E LTR mark، \u200F RTL mark، \u202BRTL embedding). هذه المحارف تُغيّر طول السلسلة دون أن تُرى. مقارنة نصّيّة (name === "محمد") قد تفشل لأنّ النصّ يحوي محرف اتّجاه مخفي. الحلّ: عند مقارنة نصوص عربيّة من إدخال المستخدم، نظّفها أوّلاً عبر دالّة Normalize:str.normalize('NFC').replace(/[\u200E\u200F\u202A-\u202E]/g, '').
المشكلة الرابعة: JSON-Pointer مع مفاتيح عربيّة
إذا استخدمت مفاتيح عربيّة ({"اسم": "محمد"}) فإنّ JSON Pointer (RFC 6901) يحتاج URL-encoding للمفاتيح. /اسم غير صالح كمسار، الصحيح هو /%D8%A7%D8%B3%D9%85. لذا اعتمد قاعدة محدّدة: المفاتيح الإنجليزيّة دائماً (name, email)، والقيم بأيّ لغة. هذه القاعدة توفّر عليك أيضاً صداع تعدّد اللغات في الواجهة الأماميّة.
المشكلة الخامسة: الأرقام العربيّة-الهنديّة في JSON
إذا استقبل API الخاصّ بك أرقاماً مكتوبة بالعربيّة-الهنديّة (0123456789) كنصّ، فإنّ parseInt أو Number() يُرجعان NaN أو القيمة الإنجليزيّة فقط. الحلّ: حوّلها قبل المعالجة عبر دالّة بسيطة:str.replace(/[0-9]/g, d => d.charCodeAt(0) - 1632). المنصّات السعوديّة الحكوميّة قد تُرسل أرقام هويّات بالعربيّة-الهنديّة وتسبّب أخطاء صامتة في تطبيقاتك.
أمثلة عمليّة من APIs عربيّة شائعة
القراءة عن JSON شيء، ورؤيته في إنتاج فعليّ شيء آخر. خمس بيئات يلتقي بها المطوّر في المنطقة باستمرار.
ZATCA (هيئة الزكاة والضريبة): الفاتورة الإلكترونيّة
الفاتورة المبسّطة في المرحلة الثانية تُرسل بصيغة UBL 2.1 (XML)، لكنّ بوّابة Fatoora نفسها تتحدّث REST + JSON. بنية الردّ التقليديّة:
{
"validationResults": {
"infoMessages": [],
"warningMessages": [],
"errorMessages": [],
"status": "PASS"
},
"reportingStatus": "REPORTED",
"qrCode": "AQNYWyBKYW5lXSBKYW1l..."
}ملاحظتان: الـ qrCode سلسلة Base64 لكائن TLV، والحقولvalidationResults دائماً متواجدة حتى في حالة النجاح — لا تفترض غيابها.
سلّة (Salla): إشعارات Webhook
متاجر سلّة تُرسل أحداث (طلب جديد، شحن، إلغاء) عبر Webhook بصيغة JSON. البنية ثابتة: event, merchant, created_at,data. أهمّ قاعدة: تحقّق من توقيع X-Salla-Signature قبل معالجة المحتوى — كثير من المطوّرين يتجاهل هذا ويُعرّض متجره لـ webhook spoofing.
تَب (Tap Payments): إنشاء عمليّة دفع
مزوّد دفع شعبيّ في المنطقة. طلب الإنشاء (POST /v2/charges) يحوي مبلغاً (amount) كرقم، عملةً (currency) كنصّ ISO 4217، وعميلاً (customer) ككائن. الردّ يتضمّن transaction.urlالذي تحوّل إليه المستخدم لإكمال الدفع. التذكرة: المبالغ بـ تَب بأصغر وحدة (هَلَلة)، فـ 100 ريال = 10000.
نفاذ: التحقّق الموحّد
خدمات الحكومة الرقميّة تستخدم OAuth 2.0 + OpenID Connect. الردّ من نفاذ بعد التحقّق الناجح يحوي id_token مكوّناً من ثلاث أجزاء مفصولة بنقاط (header.payload.signature). الـ payload هو JSON بـ Base64URL يتضمّن nationalId, name, iss. لا تثق به إلّا بعد التحقّق من التوقيع عبر مفتاح نفاذ العامّ.
أنظمة المؤسّسات الكبرى: ملفّات تكامل عبر SFTP
كثير من أنظمة المؤسّسات الكبرى (بنوك، شركات طاقة، أنظمة ERP قديمة) لا يزال يتبادل ملفّات JSON دفعيّة (batch) عبر SFTP بدل APIs حيّة. الإجادة هنا تتطلّب تنسيقاً صارماً: ترتيب الحقول، أصفاراً مسبقة في الأرقام ("0001")، وتواريخ بصيغة YYYYMMDD دون فواصل. الالتزام بالـ Schema الذي يقدّمه الطرف الآخر لا تفاوض فيه.
معالجة JSON الضخم: Streaming و NDJSON
عند تجاوز ملفّ JSON حدود ذاكرة الجهاز (عادةً 1-2GB)، يصبح JSON.parseمستحيلاً ويُجمّد العمليّة. ثلاث استراتيجيّات للتعامل.
الاستراتيجيّة الأولى: NDJSON (Newline-Delimited JSON)
صيغة بسيطة: كلّ سطر هو JSON مستقلّ. الفوائد ثلاث: (1) تستطيع قراءة الملفّ سطراً سطراً مع ذاكرة ثابتة بغضّ النظر عن الحجم، (2) إذا تعطّل سطر فالباقي يعمل، (3) أدوات Big Data (BigQuery, Snowflake, Databricks) تستوردها أصلياً. كلّ منصّات المراقبة الكبرى (Datadog, Loki, Elastic) تخزّن بـ NDJSON. الانتقال من JSON عاديّ إلى NDJSON تغيير جوهريّ في تصميم الأنظمة الحديثة.
الاستراتيجيّة الثانية: SAX-style Parsers
مكتبات مثل ijson في Python أو stream-json في Node.js تتعامل مع JSON كـ event stream: عثرت على بداية كائن، عثرت على مفتاح، عثرت على قيمة. الذاكرة تظلّ ثابتة. مفيد لاستخراج حقل واحد من ملفّ ضخم، أو تطبيق فلترة قبل التحميل الكامل.
الاستراتيجيّة الثالثة: تقسيم البيانات (Sharding)
إذا كان الملفّ مصفوفة ([{...}, {...}, ...]) كبيرة، قسّمها إلى ملفّات صغيرة (part_001.json ... part_100.json) وعالجها بالتوازي. نسخة احترافيّة: استخدم split أو jq في الطرفيّة لتقسيم سريع، ثمّ xargs -P أو GNU parallel لتوزيع العمل على عدّة أنوية معالجة.
تصحيح أخطاء JSON: أدوات وعِلَل شائعة
خمس رسائل خطأ متكرّرة في JSON ومعنى كلّ منها وحلّها:
«Unexpected token X in JSON at position N»
الرسالة الأشهر. سببها وجود محرف غير صالح في الموقع N. أكثر الأسباب: BOM مخفيّ، فاصلة زائدة ({"a":1,})، علامة تنصيص مفردة، تعليق (// ...). الأداة المُسعِفة: انسخ النصّ فيhttps://jsonlint.com أو في أداة منسّق JSON الخاصّة بنا، وستظهر لك الموقع الدقيق مع الإصلاح المقترح.
«Unexpected end of JSON input»
سببها قطع قبل اكتمال الكائن. أهمّ سيناريو: استدعاء response.json()قبل التأكّد من response.ok. عندما يفشل API ويُرجع HTML خطأ، تظنّ أنّك تستلم JSON وتفشل عند parsing. الحلّ: تحقّق منContent-Type دائماً قبل قراءة الجسم.
«Maximum call stack size exceeded»
رسالة JavaScript عند parsing JSON ذي تداخل عميق جداً (آلاف المستويات). نادراً ما تحصل في بيانات حقيقيّة، لكنّها مؤشّر شبه أكيد على هجوم JSON Bomb. ضع حدّاً أقصى للعمق في API الخاصّ بك (مثلاً 32 مستوىً) وارفض ما عدا ذلك.
«JSON.parse is not a function»
خطأ في بيئات قديمة جداً (IE7-) أو في WebWorker مُعطّل. حلّها: ترقية البيئة، أو استخدام polyfill من json2.js. في 2026 لا يوجد عذر لمواجهة هذه الرسالة.
التطابق الصامت (Silent Coercion)
ليست رسالة خطأ بل أسوأ: لا توجد رسالة. مثلاً JSON.parse("1") ينجح ويُرجع رقم 1، فإذا كنت تتوقّع كائناً ولا تتحقّق من النوع، تفشل لاحقاً برسالة مضلّلة. الحلّ: تحقّق دائماً من النوع بعد parsing (typeof parsed === 'object' && parsed !== null).
الأدوات الموصى بها
(1) أداة منسّق JSON عبر هذا الموقع — تعمل محلياً 100% بدون رفع البيانات. (2) jq في الطرفيّة لمعالجة سريعة:cat file.json | jq '.users[].email'. (3) إضافة JSON Viewer للمتصفّح لعرض ردود APIs بشكل مقروء. (4) jsondiff لمقارنة نسختين من نفس الملفّ والكشف عن الاختلافات الجوهريّة.
قائمة المراجعة قبل النشر للإنتاج
15 نقطة تفرّق بين خدمة JSON هاوية وخدمة احترافيّة جاهزة لبيئة الإنتاج:
التصميم: (1) أسماء حقول بنمط واحد (snake_case أو camelCase حصراً)، (2) لا تكرار للحقل بمعنيين مختلفين، (3) ترتيب الحقول الأكثر استعمالاً أوّلاً لقابليّة قراءة أفضل، (4) تواريخ ISO 8601 حصراً، (5) معرّفات (IDs) كنصوص لا أرقام.
الأمان: (6) تحقّق Schema قبل أيّ معالجة، (7) حدّ أقصى لحجم الجسم (1MB افتراضياً)، (8) حدّ أقصى لعمق التداخل (32)، (9) تنظيف HTML من القيم النصّية إذا كانت ستُعرض، (10) عدم الاعتماد على ترتيب المفاتيح في توقيع رقميّ إلّا عبر JSON Canonicalization.
الأداء: (11) استخدام Minify في الإنتاج، (12) gzip أو brotli على مستوى HTTP، (13) Pagination للمصفوفات الكبيرة لا إرسال 10000 عنصر دفعة واحدة، (14) ETags و Last-Modified للتخزين المؤقّت.
التوثيق: (15) كلّ نقطة نهاية API موثّقة بنموذج JSON حقيقي للطلب وللردّ، مع شرح كلّ حقل. الأدوات: OpenAPI 3.1 أو AsyncAPI 2.6. الوثائق الناقصة سبب رئيسيّ في فشل تكامل المنصّات.
ثلاثة أنماط فشل JSON موثّقة في الإنتاج
أفضل دروس JSON لا تُقرأ في الوثائق، بل في أنماط الفشل التي تتكرّر عبر الصناعة. ثلاثة أنماط موثّقة علناً، مع سيناريو توضيحيّ لكلّ منها يقرّب شكل الضرر في أنظمتنا المحلّية.
النمط الأوّل: فقدان دقّة المعرّفات الرقميّة
JavaScript يفقد دقّة الأرقام الأكبر من 2^53. المثال الموثّق الأشهر: تويتر اضطرّ في 2010 إلى إضافة حقل id_str بجانب id في API العامّ لأنّ معرّفات التغريدات ذات 64-bit كانت تُقرأ في المتصفّحات بأرقام أخيرة خاطئة — أصفار صامتة مكان الخانات الحقيقيّة. تخيّل النمط نفسه مع أرقام IBAN السعوديّة (24 خانة): إرسالها كـ number بدلstring يعني تحويلات تصل لحسابات خاطئة دون أيّ رسالة خطأ. الدرس: كلّ رقم لا تريد إجراء عمليّة حسابيّة عليه ليس رقماً، بل معرّف — أرسله نصّاً دائماً.
النمط الثاني: تسرّب بيانات عبر serialize-all
تصنّفه OWASP في قائمة API Security Top 10 (فئة Broken Object Property Level Authorization، وقبلها Excessive Data Exposure) ضمن أخطر ثغرات APIs. السيناريو النموذجيّ: فريق يضيف عموداً داخليّاً في قاعدة البيانات (تقييم ائتمانيّ داخليّ مثلاً)، والـ ORM يُضمّنه تلقائيّاً في مخرج JSON العامّ لأنّ العمليّة «serialize all columns» — فيصبح حقل داخليّ حسّاس مرئيّاً لأيّ مستخدم يفتح أدوات المطوّر في المتصفّح. الدرس: الإفصاح الصريح (whitelist) لا الحجب (blacklist). عرّف صراحةً أيّ حقول تظهر في JSON العامّ، ولا تعتمد على serialize-all. Zod وPydantic يسهّلان هذه الممارسة عبر DTOs صريحة.
النمط الثالث: الردّ بـ 200 OK قبل التحقّق من الـ Webhook
خادم يستقبل webhook من بوّابة دفع ويعيد 200 OK فوراً (لتجنّب retries) قبل التحقّق من الـ JSON. عندما تُغيّر البوّابة بنية الحمولة (حقل amount يتحوّل من رقم إلى كائن{value, currency} مثلاً)، يفشل الـ parsing صامتاً وتضيع الأحداث أيّاماً قبل أن يلاحظ أحد — لأنّ البوّابة ترى 200 OK وتعتبر التسليم ناجحاً فلا تعيد الإرسال. الدرس:لا تستجب بـ 200 OK إلّا بعد نجاح Schema validation وتخزين الرسالة الأوليّة في queue دائم. الأفضل: استلام الـ webhook ثمّ تخزينه خاماً في Kafka أو Redis Stream أوّلاً، ثمّ معالجته لاحقاً مع إمكانيّة إعادة التشغيل (replay) عند إصلاح الخلل.
JSON داخل قواعد البيانات: PostgreSQL، MySQL، MongoDB
JSON لم يعد صيغة تناقل فقط، بل أصبح نوع عمود أصيل في قواعد البيانات الحديثة. ثلاثة سيناريوهات، ثلاثة أدوات.
PostgreSQL: JSONB أو JSON؟
PostgreSQL يدعم نوعين: JSON يخزّن النصّ كما هو (أسرع في الإضافة، أبطأ في الاستعلام)، وJSONBيخزّن بنية ثنائيّة مع دعم فهارس GIN (أبطأ قليلاً في الإضافة، أسرع بفارق هائل في الاستعلام المُفهرس). القاعدة العمليّة: استخدم JSONB دائماً إلّا إذا كنت تخزّن سجلّ تدقيق (audit log) لا تستعلم عنه إلّا نادراً. فهرس GIN يسمح باستعلامات مثل «jsonb -> أيّ حقل -> أيّ قيمة» بسرعة فهرس عاديّ.
-- جدول عملاء بحقل metadata مرن
CREATE TABLE customers (
id BIGSERIAL PRIMARY KEY,
email TEXT NOT NULL,
metadata JSONB NOT NULL DEFAULT '{}'
);
CREATE INDEX idx_metadata ON customers USING GIN (metadata);
-- بحث أسرع بكثير مع فهرس GIN
SELECT * FROM customers WHERE metadata @> '{"city":"الرياض"}';تحذير: لا تجعل JSONB عموداً لبيانات ببنية ثابتة تحتاج فيها join مع جداول أخرى، أو لحقول تتغيّر باستمرار — UPDATE JSONB يعيد كتابة السطر كاملاً ويُتلف أداء الجدول تدريجيّاً (table bloat).
MySQL 8: عمود JSON والأعمدة المحسوبة
MySQL 8 دعم عمود JSON أصليّاً مع إمكانيّة «Generated Columns» لاستخراج حقل من JSON إلى عمود عاديّ وفهرسته. لا توجد فهارس GIN، لكنّ الأعمدة المحسوبة تسدّ الثغرة. أداء استعلامات JSON في MySQL أبطأ عموماً من PostgreSQL JSONB المُفهرس، لكنّه كافٍ للتطبيقات المتوسّطة.
CREATE TABLE orders ( id BIGINT PRIMARY KEY AUTO_INCREMENT, data JSON, city VARCHAR(50) GENERATED ALWAYS AS (data->>'$.city') STORED, INDEX idx_city (city) );
MongoDB: ليس JSON بل BSON
لا تخلط بينهما. MongoDB يخزّن BSON (Binary JSON) الذي يدعم أنواعاً لا توجد في JSON: ObjectId،Date، BinData، Decimal128. عندما تصدر بيانات من MongoDB إلى عميل خارجيّ، تحوّل هذه الأنواع تلقائيّاً إلى JSON لكنّ بصيغة استثنائيّة: {"$oid": "..."}،{"$date": "..."}. معالجة هذه الصيغة الخاصّة في العميل مصدر أخطاء متكرّر — استخدم EJSON.parse أو حوّلها على مستوى الخادم قبل الإرسال.
متى تخزّن JSON ومتى تُفلطحه
التوتر الدائم في تصميم قواعد البيانات: حفظ حقل بداخل JSON (مرن) أم أعمدة منفصلة (أداء أفضل)؟ القاعدة الذهبيّة: «بيانات تبحث فيها أو تحتوي join اجعلها أعمدة، بيانات تراها ككتلة واحدة اتركها في JSON». إعدادات المستخدم، metadata للأحداث، أو استجابات webhook أصليّة أمثلة على الثاني. أسعار، حالات، تواريخ إنشاء أمثلة على الأوّل.
أسئلة شائعة
ما الفرق بين JSON و Protocol Buffers (Protobuf)؟
JSON نصّي ومقروء للإنسان، لكنه أكبر حجماً وأبطأ تحليلاً بفارق واضح. Protobuf (ثنائي binary) أفضل لـ microservices داخلية و gRPC. JSON أفضل لـ REST APIs عامة، webhooks، وأي تكامل مع طرف ثالث. القاعدة: JSON للخارج، Protobuf للداخل.
متى أستخدم NDJSON (Newline-Delimited JSON)؟
NDJSON = كل سطر كائن JSON مستقل (بدون مصفوفة مغلّفة). مثالي لـ: (1) logs و events streams (Datadog, Loki), (2) تصدير بيانات كبيرة من BigQuery/Snowflake, (3) ملفات أكبر من الذاكرة (streaming line-by-line). المتصفّحات لا تدعمه أصلياً، استخدم fetch + ReadableStream.
هل JSON.stringify تحفظ ترتيب المفاتيح؟
في JavaScript الحديث (ES2015+) و V8 تحفظ ترتيب الإدخال للمفاتيح النصّية، لكنّ معيار JSON رسمياً لا يضمن ترتيب المفاتيح. لو اعتمدت على ترتيب معيّن (مثل ـ hashing/signing/checksums) استخدم JSON Canonicalization (RFC 8785) الذي يرتّب المفاتيح أبجدياً بطريقة قابلة للتكرار. حرج جداً في Webhooks و JWT signatures و Blockchain.
هل JSON هو نفسه JavaScript Object؟
لا. JSON نص (string). JavaScript Object كائن في الذاكرة. التحويل: JSON.parse(jsonString) ينتج كائن، JSON.stringify(obj) ينتج نص JSON.
كيف أكتب تعليقات في JSON؟
لا يمكن في JSON القياسي. الحلول: (1) استخدم JSON5 الذي يدعم تعليقات، (2) أضف حقل _comment بدلاً من تعليق فعلي.
هل JSON حسّاس لحالة الأحرف؟
نعم. True غير صالح، true صالح. أسماء المفاتيح حسّاسة أيضاً: {"Name"} و {"name"} مفتاحان مختلفان.
ما الحجم الأقصى لملف JSON؟
المعيار نفسه لا يحدّد حجماً. لكن المتصفحات والـ APIs عادةً تحدّ بـ 1-10MB. للبيانات الكبيرة، استخدم NDJSON (سطر JSON لكل entry) أو streaming.
هل يدعم JSON تواريخ؟
لا، رسمياً. اتفاقياً، تُكتب التواريخ كنصوص بصيغة ISO 8601: "2026-05-16T14:30:00Z". JSON.stringify(new Date()) يفعل هذا تلقائياً.
JSON أم JSONC أم JSON5؟
JSON: المعيار الرسمي، الأكثر دعماً. JSONC: JSON + تعليقات (يستخدمه VS Code). JSON5: JSON + تعليقات + trailing commas + مفاتيح بلا تنصيص. للنقل عبر الشبكة استخدم JSON. للإعدادات الداخلية يجوز JSONC.
هل أحتاج إنترنت لمنسّق JSON؟
أداتنا تعمل 100% محلياً في المتصفح — بياناتك لا تُرسل لأي خادم. تستخدم JSON.parse الأصلي في المتصفح. هذا مهم جداً عند معالجة بيانات حسّاسة (أرقام عملاء، فواتير، أسرار API).
لماذا تفشل JSON.parse عند فتح ملف صادر من Excel أو Notepad؟
السبب الأكثر شيوعاً: إضافة BOM (Byte Order Mark) أوّل الملفّ تلقائيّاً. الحلّ: في Notepad اختر «Save As» ثمّ «UTF-8 (no BOM)». في VS Code: اضغط على «UTF-8 with BOM» أسفل الشاشة وغيّرها إلى «UTF-8» العاديّ. أو في الكود استخدم JSON.parse(text.replace(/^\uFEFF/, '')) لإزالته برمجيّاً.
لماذا أستخدم Zod أو Pydantic؟
لثلاثة أسباب: (1) توليد types تلقائيّاً من schema واحد بدل كتابة schema وtypes مرّتين. (2) رسائل خطأ واضحة للعميل بدل «Invalid JSON». (3) تحويل تلقائيّ للأنواع (نصّ «2026-05-21» يصبح Date تلقائيّاً). العائد على الاستثمار خلال أسبوعين.
أيّ تنسيق أختار لملفّات الإعدادات (config)؟
للإعدادات البسيطة: TOML (بسيط مثل INI). للإعدادات المتوسّطة: YAML (أكثر قراءة). لإعدادات تحتاج تعليقات: JSONC. للبرمجة وإعدادات ديناميكيّة: JSON عاديّ. تجنّب XML إلّا إذا أجبرت (تكامل مع SOAP أو ZATCA UBL).
خلاصة
JSON ليس مجرد تنسيق نصّي — هو لغة التبادل العالمية للويب الحديث. إتقانه أساسي لأي مطور. القواعد الذهبية:
- لا تكتب JSON يدوياً — استخدم دائماً
JSON.stringify(). - تحقق من صحة JSON قبل الإرسال (parse → re-stringify).
- استخدم UTF-8 بدون BOM للملفات.
- للإنتاج: استخدم Minify. للتطوير: استخدم Pretty Print.
- للأرقام الكبيرة (IDs): أرسلها كنصوص.
- للتواريخ: ISO 8601 دائماً.
استخدم منسّق JSON أعلى الصفحة لتنسيق وتحقق وتحويل JSON الخاص بك. تعمل الأداة محلياً 100%.
أدوات ذات صلة
أدوات أخرى مجانية على ArabToolBox، كلها تعمل في متصفّحك بدون تسجيل.
- محوّل Excel ↔ CSV ↔ JSONحوّل بين Excel، CSV، JSON بدقة + دعم العربية
- منسّق SQLنسّق استعلامات SQL — يدعم MySQL، PostgreSQL، MS SQL
- محوّل YAML ↔ JSON ↔ TOMLتحويل بين صيغ الإعدادات الثلاث + تحقق فوري
- Base64 ترميز وفكترميز وفك Base64 — نصوص، صور، ملفات — محلياً 100%
- ترميز URLترميز URL مع دعم كامل للأحرف العربية + Query Strings
- تدقيق AEOافحص ظهور موقعك في ChatGPT, Perplexity, Gemini, Claude