Un client browser e un servizio Node.js dovrebbero produrre lo stesso Base64 per gli stessi byte. Non è necessario che utilizzino lo stesso API per farlo. L'accordo importante riguarda la rappresentazione in byte del testo, l'alfabeto e il trattamento del riempimento e dell'input non valido.
Browser: rendere esplicito il passaggio UTF-8
Le funzioni tradizionali del browser operano su stringhe di byte. Converti testo Unicode con TextEncoder, quindi codificare quei byte. Sul percorso di ritorno, ricostruisci un array di byte e decodifica UTF-8 in modo esplicito. Questo esempio utilizza un ciclo per evitare di espandere un array di grandi dimensioni in argomenti di funzione, sebbene un codificatore di file di produzione dovrebbe comunque utilizzare blocchi delimitati o un byte appropriato API.
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); // 中文😊
Node.js: mantiene Buffer al limite del byte
Buffer.from(text, 'utf8') rende visibile la codifica del testo. Chiamando toString('base64') quindi rappresenta quei byte. La decodifica in Buffer preserva i dati binari; la conversione immediata in una stringa UTF-8 è appropriata solo quando si sa che il payload è testo.
import { Buffer } from 'node:buffer';
const encoded = Buffer.from('中文😊', 'utf8').toString('base64');
console.log(encoded); // 5Lit5paH8J+Yig==
const bytes = Buffer.from(encoded, 'base64');
console.log(new TextDecoder('utf-8', { fatal: true }).decode(bytes)); // 中文😊
L'errore fatale TextDecoder nell'esempio è intenzionale. La conversione di stringa ordinaria Buffer UTF-8 può inserire caratteri sostitutivi per input non validi. Una corretta visualizzazione del testo nasconderebbe quindi che i byte originali non possono essere rappresentati fedelmente.
Concordare la convalida separatamente
Il decodificatore Base64 del nodo accetta alcuni moduli di input che un'applicazione più rigorosa potrebbe rifiutare. Non utilizzare una conversione Buffer riuscita come prova che è stata fornita la rappresentazione canonica di un protocollo. Se la sintassi esatta è importante per firme, chiavi di cache o serializzazione interoperabile, controllala prima della decodifica.
Per un test di regressione condiviso, includere ASCII, cinese, emoji, un byte zero, byte FF e tutte le lunghezze attorno a un limite di tre byte. Confronta i byte tra i runtime. Testare anche l'output URL-safe con un dispositivo che contenga effettivamente i caratteri sostituiti; un input il cui output è composto solo da lettere non può dimostrare che l'opzione variante funzioni.
Durante la lettura dei file in Node, mantieni il Buffer restituito anziché applicare una codifica di testo al file letto. Nel browser, utilizzare File.arrayBuffer(). Queste piccole scelte di confine evitano la maggior parte della corruzione accidentale. Vedi Node.js Buffer per il comportamento del nodo e MDN: btoa() per il contratto della stringa di byte del browser.