Base64 in de browser en Node.js: contract van één byte, twee API's

Gebruik TextEncoder in browsers en Buffer in Node.js, en test vervolgens hun uitvoer met dezelfde Unicode- en binaire apparaten.

Een browserclient en een Node.js-service moeten dezelfde Base64 produceren voor dezelfde bytes. Ze hoeven hiervoor niet dezelfde API te gebruiken. De belangrijke overeenkomst is de byteweergave van tekst, het alfabet en de behandeling van opvulling en ongeldige invoer.

Browser: maak de stap UTF-8 expliciet

De traditionele browserfuncties werken op bytestrings. Converteer Unicode-tekst met TextEncoderen codeer vervolgens die bytes. Reconstrueer op het retourpad een bytearray en decodeer UTF-8 expliciet. In dit voorbeeld wordt een lus gebruikt om te voorkomen dat een grote array wordt uitgebreid met functieargumenten, hoewel een encoder voor productiebestanden nog steeds begrensde chunks of een geschikte byte API moet gebruiken.

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: houd Buffer op de bytegrens

Buffer.from(text, 'utf8') maakt de tekstcodering zichtbaar. Bellen toString('base64') vertegenwoordigt dan die bytes. Bij het decoderen naar een Buffer blijven binaire gegevens behouden; onmiddellijk converteren naar een UTF-8-tekenreeks is alleen geschikt als bekend is dat de payload uit tekst bestaat.

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)); // 中文😊

De fatale TextDecoder in het voorbeeld is opzettelijk. Bij gewone Buffer UTF-8 tekenreeksconversie kunnen vervangende tekens worden ingevoegd voor ongeldige invoer. Een succesvolle tekstweergave zou dan verhullen dat de originele bytes niet getrouw konden worden weergegeven.

Spreek de validatie afzonderlijk af

De Base64-decoder van het knooppunt accepteert enkele invoervormen die een strengere toepassing mogelijk afwijst. Gebruik een succesvolle Buffer-conversie niet als bewijs dat de canonieke representatie van een protocol is geleverd. Als de exacte syntaxis van belang is voor handtekeningen, cachesleutels of interoperabele serialisatie, controleer deze dan voordat u gaat decoderen.

Voor een gedeelde regressietest neemt u ASCII, Chinees, emoji, een nulbyte, byte FF en alle lengtes rond een grens van drie bytes op. Vergelijk bytes over runtimes. Test ook de URL-veilige uitvoer met een armatuur die daadwerkelijk de vervangende tekens bevat; een invoer waarvan de uitvoer alleen uit letters bestaat, kan niet bewijzen dat de variantoptie werkt.

Wanneer u bestanden in Node leest, bewaar dan de geretourneerde Buffer in plaats van een tekstcodering toe te passen op het gelezen bestand. Gebruik in de browser File.arrayBuffer(). Deze kleine grenskeuzes vermijden de meeste toevallige corruptie. Zie Node.js Buffer voor knooppuntgedrag en MDN: btoa() voor het byte-stringcontract van de browser.