JavaScript Base64 ricette per JSON, file e array di byte

Utilizza le ricette UTF-8-safe JavaScript per i payload JSON e i file selezionati senza trattare accidentalmente i dati binari come testo.

Il codice utile Base64 inizia decidendo quale sia effettivamente l'input. Una stringa JavaScript necessita di una codifica di caratteri; un file contiene già byte; un valore JSON deve prima essere serializzato. Mantenere questi passaggi visibili semplifica il debug e impedisce la doppia codifica accidentale.

Codifica un piccolo valore JSON

Serializza il valore esattamente una volta, codifica la stringa come UTF-8, quindi codifica i byte come Base64. Questo esempio include un campo nonASCII per rilevare le implementazioni che funzionano solo con l'inglese. È destinato a piccoli carichi utili; la stringa di byte temporanea aumenta l'utilizzo della memoria.

const value = { message: '你好', count: 3 };
const text = JSON.stringify(value);
let binary = '';
for (const byte of new TextEncoder().encode(text)) {
  binary += String.fromCharCode(byte);
}
const encoded = btoa(binary);
const bytes = Uint8Array.from(atob(encoded), c => c.charCodeAt(0));
const json = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
console.log(JSON.parse(json).message); // 你好

Una decodifica Base64 riuscita non garantisce la validità di JSON. Tratta la decodifica UTF-8 e JSON.parse come punti di fallimento separati. Quando il contenuto decodificato è già una stringa contenente JSON, serializzandolo nuovamente si aggiungono virgolette ed escape; che cambia il carico utile.

Legge un file selezionato come byte

Per un navigatore File, utilizzare arrayBuffer() quando hai bisogno dei byte sottostanti. Non utilizzare file.text() per un'immagine, un archivio o un file crittografato: le sequenze di caratteri non valide possono diventare caratteri sostitutivi. Se la tua destinazione necessita di dati URI, FileReader.readAsDataURL() fornisce il wrapper e i dati Base64.

// file is a File selected by the user.
const bytes = new Uint8Array(await file.arrayBuffer());
console.log(bytes.byteLength); // original file size in bytes
// Pass bytes to a byte-oriented encoder, not TextEncoder.

Controlli di andata e ritorno che rilevano errori reali

Confronta i byte decodificati con l'array di byte originale. Confrontando schermate o nomi di file non è possibile rilevare un byte modificato. Include input vuoto, tutti i valori di byte da 0 a 255, testo cinese, emoji e un payload la cui lunghezza lascia uno o due byte nel gruppo finale. Per un batch di file, conserva il nome, la dimensione e il risultato di ciascun file in modo indipendente in modo che un errore non possa sovrascrivere un altro output riuscito.

Mantieni le conversioni locali a meno che il tuo flusso di lavoro non chiami intenzionalmente un API. Una richiesta di rete contenente l'output codificato invia comunque i dati sottostanti in forma reversibile. Per il comportamento delle stringhe di byte e la limitazione Unicode della funzione del browser, vedere MDN: btoa().