Outils de développement · Encodeur et décodeur Base64
Pourquoi btoa() lance des emoji et comment encoder UTF-8 en Base64 en JavaScript
· Comment ça marche
base64 unicode encodage
btoa() n'accepte que les caractères jusqu'à U+00FF, donc le texte accentué, le CJK et les emoji sont lancés. Cet article montre ce que la fonction attend réellement et comment TextEncoder vous obtient une chaîne UTF-8 Base64 correcte.
Pourquoi btoa peut utiliser Unicode et coder silencieusement un accent
L'appel de btoa("😀") renvoie InvalidCharacterError car l'emoji ne peut pas tenir dans une unité de code d'un seul octet. Une erreur plus subtile est btoa("é") : le é précomposé est U+00E9, inférieur à 256, donc btoa l'accepte mais code le latin-1 byte E9, pas UTF-8 bytes C3 A9. Le même accent visible écrit sous la forme e plus une marque combinée peut être lancé car la marque est en dehors de la plage acceptée. Le raccourci du classeur « un accent lance » nécessite cette qualification : une chaîne peut échouer bruyamment ou silencieusement et produire les mauvais octets.
Ce que btoa() code réellement : une chaîne binaire d'unités de code 0 à 255 - pourquoi la fonction a été conçue autour du latin-1 bytes plutôt que du texte Unicode
btoa consomme une « chaîne binaire » : chaque unité de code de caractère JavaScript doit être comprise entre 0 et 255 et représente un octet. Il ne comprend pas le codage, le langage ou la normalisation du texte Unicode. Un emoji astral est représenté par deux unités de code de substitution UTF-16, toutes deux beaucoup plus grandes que 255, donc l'envoi direct de la chaîne JavaScript brute ne peut pas fonctionner. Traitez la sortie comme un codage d'octets et non de caractères abstraits.
UTF-8 d'abord, Base64 ensuite - pourquoi le texte doit devenir des octets avant qu'un alphabet Base64 ne s'applique
TextEncoder transforme d'abord une chaîne JavaScript en sa séquence UTF-8 byte. Transformez ensuite chaque octet en caractère de chaîne binaire et transmettez cette chaîne binaire à btoa, ou utilisez une autre API qui accepte directement les octets. Pour le décodage, atob renvoie la chaîne binaire ; récupérer ses valeurs d'octets et les donner à TextDecoder("utf-8"). ToolAcre utilise un décodeur strict qui refuse l'UTF-8 mal formé au lieu d'insérer silencieusement des caractères de remplacement.
Exemple concret : encodage de 'café 😀' avec TextEncoder et btoa — la séquence d'octets, la chaîne binaire intermédiaire et la sortie finale
Pour le café texte littéral 😀, les UTF-8 bytes sont 63 61 66 C3 A9 20 F0 9F 98 80 en hexadécimal : ASCII c-a-f, deux octets pour é, un espace et quatre octets pour l'emoji. La base64 de ces dix octets est Y2Fmw6kg8J+YgA==. Le remplissage et l'alphabet décrivent uniquement les octets ; ils n'étiquetent pas la langue. Comparez un échec direct btoa("café 😀") avec le mode UTF-8 de ToolAcre, puis décodez son résultat et vérifiez que le même accent visible et les mêmes emoji survivent.
L'ancienne astuce unescape(encodeURIComponent()) et pourquoi c'est un hack - ce qu'il fait sous le capot et pourquoi il est déconseillé
Une solution de contournement historique est btoa(unescape(encodeURIComponent(text))). encodeURIComponent encode en pourcentage UTF-8 et unescape reconditionne les triplets de pourcentage en unités de code unique, mais unescape est obsolète, difficile à lire et gênant en présence de substituts isolés mal formés. Cela fait ressembler une conversion à un traitement d'URL même lorsqu'aucune URL n'existe. TextEncoder indique clairement la limite prévue : le texte devient des octets une fois, et Base64 ne fonctionne qu'après cela.
Décodage de l'autre côté - association d'atob avec TextDecoder pour que l'aller-retour se fasse sans perte
Après atob, n'appelez pas decodeURIComponent sur des octets binaires arbitraires et espérez qu'ils deviennent du texte. Convertissez les codes de caractères en Uint8Array et transmettez-les via TextDecoder. Dans l'exemple du café 😀, le résultat est la séquence UTF-8 originale de dix octets, puis la chaîne originale. Si le Base64 décode en octets d'image ou de fichier compressé, il peut ne pas représenter du tout un texte UTF-8 valide ; ToolAcre rapporte que plutôt que de prétendre que les données binaires sont une prose lisible.
Ce que cela ne couvre pas : encodage de fichiers et de blobs binaires, variantes base64url et diffusion en continu d'entrées volumineuses
Cette explication concerne le texte codé en UTF-8. Les fichiers et Blob Base64, Base64url pour les segments JWT et le codage incrémentiel de données de plusieurs gigaoctets ont des interfaces ou des besoins en mémoire différents. Base64 ne chiffre pas non plus un jeton : toute personne le détenant peut décoder les octets. Le décodeur peut accepter le remplissage et les espaces manquants courants, mais l'interopérabilité dépend toujours de savoir si la charge utile est du texte ou des données binaires arbitraires.
À retenir : encodez des octets, pas des chaînes, et vérifiez l'aller-retour – comment l'encodeur et le décodeur Base64 effectuent l'étape UTF-8 pour vous afin que les accents, CJK et emoji survivent.
Encodez des octets, pas des chaînes JavaScript brutes, puis vérifiez l'aller-retour. L'encodeur et décodeur Base64 exécute les étapes TextEncoder et TextDecoder pour vous tout en conservant le texte collé dans le navigateur. La RFC 4648 spécifie l'alphabet et le remplissage ; UTF-8 fournit le contrat caractère-octet séparé. Le mélange de ces deux couches est à l'origine à la fois d'InvalidCharacterError et de la corruption discrète Latin-1.