الأسماء atob و btoa يمكن أن يقترح تحويل النص العادي. عقد المتصفح الخاص بهم أضيق: يقومون بالتحويل بين نص Base64 وسلسلة تمثل قيم أحرفها بايتات فردية. سلسلة البايت هذه عبارة عن حاوية، وليست وعدًا بأن النتيجة هي نص Unicode قابل للقراءة.
سلسلتين مختلفتين
تستخدم سلاسل JavaScript وحدات الكود UTF-16. تقوم سلسلة البايت بتقييد كل قيمة حرف بشكل متعمد إلى 0–255. btoa('Hello') يعمل لأن قيم ASCII تناسب هذا النطاق. btoa('你好') يفشل لأن هذه الأحرف لا تتناسب مع بايت واحد. حتى الشخصية المناسبة يمكن أن تكون مضللة: btoa('é') يشفر البايتة المفردة E9، وليس UTF-8 بايت C3 A9 المتوقعة من قبل العديد من الخدمات.
console.log(btoa('é')); // 6Q== (byte E9)
console.log(btoa(String.fromCharCode(0xc3, 0xa9))); // w6k= (UTF-8)
ضع تحويل UTF-8 حول وظائف البايت
TextEncoder ينتج UTF-8 بايت من النص. بعد فك التشفير Base64، قاتل TextDecoder يحول البايتات الصالحة UTF-8 إلى نص ويرفض التسلسلات غير الصالحة بدلاً من استبدالها بصمت. هذا المثال الصغير واضح بشكل متعمد بحيث تكون الحدود مرئية.
const text = '中文😊';
const bytes = new TextEncoder().encode(text);
let binary = '';
for (const byte of bytes) binary += String.fromCharCode(byte);
const encoded = btoa(binary);
console.log(encoded); // 5Lit5paH8J+Yig==
const decodedBytes = Uint8Array.from(atob(encoded), c => c.charCodeAt(0));
const decoded = new TextDecoder('utf-8', { fatal: true }).decode(decodedBytes);
console.log(decoded); // 中文😊
لا تعامل نتيجة ثنائية كسلسلة مقطوعة
atob('/w==') يمثل البايت FF. إنها غير صالحة UTF-8 بحد ذاتها، ولكنها بيانات ثنائية صالحة تمامًا. قد يكون الإجراء التالي الصحيح هو تنزيل بايت أو عرض سداسي عشري، وليس خدعة مختلفة لتحويل النص. تشغيل سلسلة البايت هذه من خلال TextEncoder سوف يقوم بتشفير الحرف U+00FF وتغيير البايتات.
وحدة فك ترميز المتصفح ليست أيضًا مدققًا كاملاً للبروتوكول. يمكن أن تختلف المسافة البيضاء والحشوة المحذوفة المقبولة عن متطلبات التطبيق الصارمة. إذا كان البروتوكول يتطلب تشفيرًا أساسيًا، فقم بالتحقق من صحة الأبجدية والحشو والبتات غير المستخدمة بشكل منفصل. بالنسبة للملفات الكبيرة، تجنب نشر مصفوفة بايت كاملة فيها String.fromCharCode(...bytes); يمكن أن تفشل حدود عدد الوسائط قبل وقت طويل من أن يصبح الملف كبيرًا بشكل غير عادي.
اقرأ عقود المتصفح في MDN: أتوب () و MDN: بتوا (). يجب أن يقرر التطبيق ما إذا كان يريد تحويلاً متساهلاً، أو مدققًا صارمًا، أو سير عمل للحفاظ على الملف، بدلاً من افتراض أن هذه هي نفس المهمة.