أدوات المطور · التشفير ووحدة فك التشفير Base64
Base64 في JSON واجهات برمجة التطبيقات: لماذا يتم تشفير الحقول الثنائية وما يكلفك ذلك
· لماذا يهم
base64 ترميز
JSON لا يحتوي على نوع بايت، لذلك عادةً ما يتم ترميز البيانات الثنائية باستخدام Base64 في سلسلة. يشرح هذا المنشور سبب وجود هذه الاتفاقية، وما تكلفته من حيث الحجم وCPU، ومتى تكون نقطة النهاية الثنائية المنفصلة هي الخيار الأفضل.
الحقل PDF الذي سيطر على الاستجابة - حمولة ملموسة API حيث تفوقت نقطة Base64 الواحدة على كل شيء آخر
تحتوي الاستجابة API على كائن كبير به حقل واحد يهيمن على حجم الحمولة. الاستجابة هي JSON، لذا فإن كل قيمة عبارة عن سلسلة أو رقم. معظم الحقول صغيرة: معرفات المستخدم، والطوابع الزمنية، ورموز الحالة. يحتوي أحد الحقول على imageData أو fileContents وهو عبارة عن سلسلة Base64 بحجم 40 كيلو بايت. الاستجابة بأكملها هي 50 كيلو بايت. يمثل هذا الحقل الفردي 80 بالمائة من عملية النقل، وهو ما يبدو إسرافًا لأن الخادم أرسله على هيئة بايتات في الأصل ويحتاج العميل إلى بايتات مرة أخرى في النهاية.
قام Base64 بحل هذه المشكلة: JSON لا يحتوي على نوع بايت أصلي، لذا يجب تغليف البيانات الثنائية في سلسلة. يقوم Base64 بتحويل البايتات العشوائية إلى ASCII أحرف آمنة في JSON. يجب على كل من العميل والخادم التشفير عند الإرسال وفك التشفير عند الاستلام، مع إضافة CPU الحمل. وتكون الحمولة الناتجة أكبر بنحو الثلث من البايتات الأولية. يشرح هذا المنشور سبب وجود هذه الاتفاقية، وما هي تكلفتها عمليًا، ومتى يكون كسر قيد JSON بنقطة نهاية ثنائية منفصلة أمرًا يستحق العناء.
لماذا لا يمكن لـ JSON أن تحمل وحدات البايت الأولية — يجب أن تكون السلاسل عبارة عن نص Unicode صالح، لذا تحتاج وحدات البايت العشوائية إلى غلاف نصي
JSON هو تنسيق نصي حيث يجب أن تكون كافة القيم عبارة عن نص Unicode صالح. تحدد المواصفات السلاسل والأرقام والقيم المنطقية والصفرية. لا يحتوي على مصفوفة بايت أو نوع مخزن مؤقت. إذا احتاج API إلى إرجاع بيانات ثنائية مثل صورة أو توقيع تشفير أو تحميل ملف، فلا يمكنه وضع البايتات الأولية في كائن JSON مباشرة. قد تحتوي البايتات على أحرف يفسرها المحللون JSON كعلامات هيكلية. يمكن للبايت الفارغ في منتصف النقطة الثنائية إنهاء سلسلة مبكرًا أو كسر المحلل اللغوي.
الحل الشائع هو ترميز البيانات الثنائية كـ Base64، مما يؤدي إلى إنتاج سلسلة من ASCII من الأحرف التي يتعامل معها المحللون JSON كنص عادي. يقوم العميل المتلقي بعد ذلك بفك تشفير Base64 مرة أخرى إلى وحدات البايت ويستخدمها. تحدث خطوة التشفير هذه على المستوى API، وهي مخفية عن معظم المطورين، ولكنها تكلفة حقيقية تتراكم عندما تقوم واجهات برمجة التطبيقات بإرجاع العديد من الحقول الثنائية. تكاليف Base64 في JSON مركبة عبر دورة الاستجابة للطلب. عقوبة الحجم هي الأولى: إخراج Base64 أكبر بحوالي 33 بالمائة من مدخلاته بسبب الحمل الزائد للتشفير.
التكاليف: ثلث البايتات الإضافية ووقت فك التشفير ونسخ الذاكرة - حيث تظهر كل تكلفة في عميل نموذجي
يصبح ملف الفيديو الذي تبلغ حجمه 30 ميغا بايت 40 ميغا بايت عند ترميز Base64. يؤدي تنزيل 40 بدلاً من 30 ميغابايت إلى تكبد عرض النطاق الترددي والبطارية على الأجهزة المحمولة، والوقت للمستخدمين الذين يستخدمون اتصالات بطيئة. التكلفة الثانية هي CPU من الوقت. يجب أن يقوم الخادم بتشفير البيانات الثنائية كـ Base64 قبل أن يتم تحويلها إلى JSON. يجب على العميل تحليل JSON ثم فك تشفير كل حقل Base64 إلى وحدات البايت. بالنسبة للاستجابة ذات الحقول الثنائية المتعددة أو العميل الذي يعالج آلاف الاستجابات، يتراكم هذا الوقت الذي يبلغ CPU.
على الأجهزة المقيدة مثل الهواتف، تستهلك عمليات السلسلة JavaScript وTextDecoder المستخدم لفك تشفير Base64 البطارية وتبطئ التطبيق. التكلفة الثالثة هي الذاكرة: يقوم المحلل اللغوي JSON بإنشاء كائن سلسلة للحقل Base64، ثم يقوم فك التشفير بإنشاء نسخة أخرى كـ Uint8Array. يتم إنشاء حقل كبير مرتين في الذاكرة قبل أن يتمكن التطبيق من استخدامه. مثال عملي يوضح التكلفة. لنفترض أن نقطة النهاية API تقوم بإرجاع بيانات ملف تعريف المستخدم بما في ذلك صورة رمزية تبلغ 100 كيلوبايت. يقرأ الخادم الصورة من القرص بالبايت، ويشفرها إلى Base64، ويضمنها في الاستجابة JSON.
مثال عملي: فحص حقل Base64 من استجابة API - فك تشفيره في المتصفح لتأكيد ما أرسله الخادم بالفعل
تبلغ استجابة JSON الآن حوالي 135 كيلو بايت (33% الحمل الزائد بالإضافة إلى الحقول الأخرى). يقوم العميل بتنزيل 135 كيلو بايت بدلاً من 100. في المستعرض، يقوم المحلل اللغوي JSON بإنشاء كائن سلسلة JavaScript لبيانات Base64.
عندما يحتاج التطبيق إلى الصورة، فإنه يستدعي وحدة فك الترميز Base64، مما يؤدي إلى إنشاء Uint8Array بقيمة 100 كيلو بايت الأصلية. خلال المللي ثانية القليلة من فك التشفير، يكون كلا الكائنين موجودين في الذاكرة. إذا عرضت الصفحة عشرة ملفات شخصية مع صور رمزية، فسيتم مضاعفة التكلفة. البديل هو أن يقوم API بإرجاع استجابة JSON مع URL منفصل لكل مورد أفاتار، مما يسمح للمتصفح بالتعامل مع تنزيلات الصور من خلال التخزين المؤقت الأصلي والعرض التدريجي وإدارة الذاكرة.
البدائل: عناوين URL للتنزيل متعددة الأجزاء ومنفصلة ونقاط نهاية ثنائية خام - المفاضلات لكل منها
تعتمد المفاضلة بين تضمين الملف الثنائي في JSON وجلبه بشكل منفصل على غرض API وأنماط الاستخدام. بالنسبة لصفحة نتائج البحث التي تعرض مئات الصور المصغرة الصغيرة، فإن جلب كل منها كطلب منفصل يؤدي إلى إلغاء HTTP تجمع الاتصالات والتخزين المؤقت. قد يكون تضمينها كـ Base64 في الاستجابة JSON أسرع. بالنسبة لصفحة الملف الشخصي التفصيلية التي تطلب صورة أو صورتين عاليتي الدقة، فمن الواضح أن التنزيلات المنفصلة هي الأفضل. يجب أن توضح وثائق API الحد الأقصى لحجم حقول Base64 ومتى يجب أن يتوقع العملاء نقاط نهاية منفصلة.
إذا تجاوز الحقل بانتظام كيلوبايت أو اثنين، فإن استراتيجية Base64 المضمنة هي إشارة إلى أن تصميم API يحتاج إلى إعادة النظر. توجد بدائل لـ Base64 في JSON ولكن لكل منها مقايضات. تفصل استجابات MIME متعددة الأجزاء بين الثنائي والنص، لذا يتم إرسال القسم الثنائي كبايتات أولية ويكون قسم النص فقط هو JSON. يتطلب هذا من العميل تحليل رسالة متعددة الأجزاء بدلاً من مجرد الاتصال بـ JSON.parse، مما يزيد من التعقيد. يؤدي التنزيل المنفصل URL في الاستجابة JSON إلى توجيه العميل لجلب المورد الثنائي بشكل منفصل.
اصطلاحات تستحق الذكر في مستندات API — الأبجدية القياسية مقابل الأبجدية الأساسية 64url والحشو والأحجام القصوى
يعمل هذا بشكل جيد عندما يكون المورد الثنائي كبيرًا أو يتم الوصول إليه بشكل أقل تكرارًا من بيانات التعريف. إن نقطة النهاية الثنائية الأولية التي تُرجع البايتات فقط وتتخلى عن JSON بالكامل هي أبسط طريقة ولكنها تزيل البنية التي يوفرها JSON. تُرجع بعض واجهات برمجة التطبيقات (APIs) بيانات ثنائية مضغوطة وتقوم بتشفير Base64، مما يقلل من عقوبة الحجم ولكن يضيف حملًا إضافيًا لتخفيف الضغط. يعتمد الاختيار على الاستخدام المتوقع: الحقول الصغيرة مضمّنة بشكل جيد، والحقول الكبيرة تنتمي إلى موارد منفصلة، والبيانات المنظمة تستحق الاحتفاظ بها في JSON حتى مع تكلفة Base64.
الاتفاقيات مهمة لقابلية التشغيل البيني. يجب أن تقوم واجهات برمجة التطبيقات التي تقوم بتشفير البيانات الثنائية باستخدام Base64 بتوثيقها بوضوح وتحديد ما إذا كانت الأبجدية قياسية أم URL آمنة. يستخدم Base64 القياسي + و/, وهي آمنة في سلاسل JSON ولكن ليس في عناوين URL. URL-يستبدلها Base64 الآمن بـ - و _، وهو مناسب للبيانات: معرفات URI ولكن تم الهروب منها دون داعٍ في JSON. يجب أن تحدد الوثائق ما إذا كان سيتم تضمين الحشو أو حذفه، لأن كلاهما Base64 صالح ولكن العميل الذي يتوقع الحشو ويتلقى بيانات غير مبطنة سوف يفشل بصمت أو ينتج بيانات غير صحيحة.
ما لا يغطيه هذا — protobuf، CBOR وتنسيقات التسلسل الثنائي الأخرى
بالنسبة للحقول الكبيرة جدًا أو التي يتم تحديثها بشكل متكرر، يعد توثيق نقطة نهاية ثنائية منفصلة أمرًا ضروريًا حتى لا يحاول العملاء جلب كيلو بايت من البيانات غير الضرورية. يعد تصحيح أخطاء واجهات برمجة التطبيقات باستخدام حقول Base64 أمرًا سهلاً باستخدام الأداة المناسبة. يتيح لك برنامج التشفير وفك التشفير Base64 فك تشفير أي حقل محليًا في المتصفح، دون تخزينه أو إرساله إلى أي مكان. انسخ حقل Base64 من استجابة JSON، والصقه في وحدة فك التشفير واضغط على فك التشفير. بالنسبة للبيانات الشبيهة بالنص (JSON داخل Base64، على سبيل المثال)، يظهر الإخراج الذي تم فك تشفيره على الفور.
بالنسبة للبيانات الثنائية مثل الصور، يعرض لك العرض السداسي وحدات البايت. يساعد هذا في التأكد من أن الخادم أرسل ما كنت تتوقعه وأن وحدة فك ترميز العميل لديك تعمل بشكل صحيح. إذا تم فك ترميز أحد الحقول إلى بيانات غير متوقعة، فإن المشكلة تكمن في ترميز الخادم أو في كيفية نسخ الحقل. إذا تم فك التشفير إلى كائن ثنائي كبير الحجم جزئيًا، فقد يكون الحقل قد تم اقتطاعه أو قد يكون طول Base64 خاطئًا. يعمل فك التشفير المحلي على تسريع تصحيح الأخطاء مقارنة بكتابة الحقل إلى ملف وفتح أدوات خارجية.
الخلاصة: Base64 في JSON يمثل حلاً وسطًا، لذا قم بتوثيقه - كيف يساعدك برنامج التشفير ووحدة فك التشفير Base64 على فحص الحقول المشفرة والتحقق منها محليًا
النهج العملي لـ Base64 في واجهات برمجة التطبيقات هو الوعي وليس التجنب. Base64 هي الطريقة القياسية لحمل البيانات الثنائية في JSON وهي تعمل. افهم أن كل حقل Base64 يكلف ثلث الحجم وبضعة مللي ثانية من CPU من الوقت لكل دورة استجابة للطلب. بالنسبة لبيانات التعريف المهمة الصغيرة مثل رموز المصادقة المميزة (حيث يكون JWT نفسه مشفرًا بواسطة Base64)، تكون التكلفة ضئيلة. بالنسبة للمرفقات الكبيرة، تساءل عما إذا كان يجب أن ينتقل الملف الثنائي في نفس الاستجابة أو كمورد منفصل.
قم بتوثيق نظام التشفير والحد الأقصى للأحجام في مواصفات API الخاصة بك. عند فحص الاستجابات، استخدم برنامج التشفير ووحدة فك الترميز Base64 للتحقق من فك تشفير الحقول بشكل صحيح وفهم ما أرسله الخادم بالفعل. هذا الانضباط يبقي المقايضة مرئية ويبقي القرار متعمدا وليس عرضيا.