Outils de développement · Encodeur et décodeur Base64
Que signifient atob et btoa et pourquoi ils ne comprennent que le latin-1
· Contexte
base64 javascript unicode
atob et btoa datent de Netscape et les noms signifient « ASCII vers binaire » et « binaire vers ASCII ». Cet article explique d'où ils viennent, comment les normes WHATWG les définissent et pourquoi ils n'ont jamais appris Unicode.
Un nom de fonction qui se lit comme une faute de frappe – la confusion provoquée par les noms et la réponse sur une seule ligne
atob et btoa sont des fonctions JavaScript intégrées introduites dans Netscape dans les années 1990. Les noms sont des abréviations : btoa signifie binaire vers ASCII et atob signifie ASCII vers binaire. Les noms reflètent leur âge et leur conception : ils ont été construits à l'époque où binaire signifiait une chaîne de valeurs d'octets (0-255) plutôt que le Uint8Array ou Buffer plus moderne. Le mnémonique souvent donné pour les noms est moins important que le contrat observable : une fonction mappe une chaîne binaire en Base64 et l'autre l'inverse. Ce référentiel ne documente pas la décision de dénomination originale, donc l'article évite de présenter le folklore comme un historique de navigateur source.
Les fonctions attendent une chaîne binaire : l'unité de code de chaque caractère doit être comprise dans la plage 0-255, représentant un octet. Si vous transmettez un caractère avec une unité de code supérieure à 255 (comme un emoji ou une lettre accentuée provenant de l'extérieur du latin-1), la fonction renvoie InvalidCharacterError ou produit silencieusement une sortie incorrecte. btoa (binaire en ASCII) encode une chaîne binaire en base64.
Ce que les noms suggèrent et ce que prouve réellement le contrat de chaîne d'octets
L'entrée doit être une chaîne où chaque caractère est un octet (unité de code 0-255). btoa(hello) code les octets ASCII en base64 et renvoie aGVsbG8=. btoa avec la lettre e-acute semble fonctionner car la lettre latine précomposée 1 e-acute (U+00E9) a une unité de code de 233, qui se trouve dans 0-255. Cependant, btoa le code comme un seul octet, 0xE9, et non comme les UTF-8 octets 0xC3 0xA9 que e-acute devrait produire. Avant que les tableaux typés ne deviennent le conteneur d'octets normal, les API JavaScript utilisaient des chaînes dont les unités de code représentaient des octets. Ce modèle reste visible car btoa rejette les unités de code supérieures à 255. La chronologie précise des produits n'est pas établie par ces fichiers ; la limite de défaillance est établie par des tests exécutables.
Cette corruption silencieuse est plus dangereuse qu'une erreur : le résultat semble bon mais est faux. atob (ASCII vers binaire) décode la base64 en une chaîne binaire. atob(aGVsbG8=) renvoie bonjour. La sortie est une chaîne binaire où l'unité de code de chaque caractère est 0-255, représentant un octet. Si vous souhaitez convertir cela en texte Unicode approprié, vous devez interpréter les octets comme UTF-8 et les décoder avec TextDecoder.
L'ancien modèle de chaîne binaire : comportement observable sans réclamation non vérifiée de l'historique du navigateur
Pour ASCII, cette étape supplémentaire n'est pas nécessaire (ASCII est un sous-ensemble de UTF-8), mais pour tout octet non-ASCII, elle est essentielle. atob ne fait pas cette interprétation ; il renvoie les octets bruts sous forme de chaîne binaire.
Les normes WHATWG (les normes de vie pour les API Web) définissent atob et btoa dans la spécification HTML. La définition inclut un algorithme de décodage en base64 indulgent pour atob : il ignore les espaces et accepte le remplissage manquant, rendant le base64 du monde réel (y compris le base64 enveloppé dans MIME avec des sauts de ligne) décodable. ToolAcre normalise les espaces, la ponctuation sécurisée pour les URL et le remplissage manquant avant d'appeler le décodeur du navigateur. Il copie ensuite les unités de code renvoyées dans Uint8Array et applique un décodeur UTF-8 fatal. Cette combinaison sépare la syntaxe Base64 indulgente de l’interprétation stricte du texte.
Comportement actuel dans cette implémentation – normalisation de l'alphabet indulgente et décodage de texte UTF-8 strict
La signature de la fonction n'a pas changé, mais la définition des normes fait autorité pour ce que fait la fonction. Pourquoi atob et btoa n'acceptent-ils que le latin-1 ? Car lors de leur conception dans les années 1990, JavaScript ne disposait pas de moyen de représenter directement les octets (pas de Uint8Array ou ArrayBuffer). La seule façon de transmettre des octets à une fonction était sous forme de chaîne où chaque caractère représente un octet.
C'est ce qu'on appelle une chaîne binaire et prête à confusion selon les normes modernes. Une chaîne JavaScript est du texte Unicode et non une séquence d'octets. La conception a confondu les deux : une chaîne où chaque unité de code est 0-255 est une chaîne binaire. Le nom reflète l'époque : ASCII en btoa signifiait littéralement sept bits pour le texte ASCII, mais l'implémentation accepte n'importe quel octet (0-255). L'ajout d'un mode Unicode directement à btoa modifierait son contrat de longue date en matière de chaînes d'octets et risquerait la compatibilité. La source examinée compose à la place TextEncoder avant l'encodage. Cet article peut vérifier cette composition ; il omet les affirmations sur les motivations du comité des normes qui ne sont pas enregistrées dans le référentiel.
Exemple pratique : tracer Forgiving-base64 sur une chaîne avec des espaces et un remplissage manquant – ce qu'Atob accepte et qu'un décodeur strict rejette
Les alternatives modernes évitent le modèle de chaîne binaire. L'API Encoding fournit TextEncoder pour convertir le texte en UTF-8 octets et TextDecoder pour reconvertir UTF-8 octets en texte.
L'encodage et le décodage Base64 sont désormais spécifiés dans la spécification HTML pour les chaînes (atob et btoa) et les tableaux typés. L'outil d'encodage et de décodage Base64 utilise TextEncoder et TextDecoder autour d'atob et btoa, afin que vous puissiez encoder et décoder en toute sécurité du texte Unicode sans les limitations Latin-1. Une valeur espacée ou non complétée réussit car la normalisation supprime les espaces et restaure la longueur de bloc requise. Une valeur dont la longueur nettoyée laisse le reste un est rejetée avant atob. Cette distinction montre ce que « pardonner » signifie ici : le formatage récupérable est accepté, la saisie structurellement impossible ne l'est pas.
Les normes les plus récentes fonctionnent sur Base64 pour les tableaux typés - décrites qualitativement, avec une note pour vérifier la prise en charge actuelle du navigateur
La gestion d'Unicode avec btoa nécessite d'abord de coder le texte en UTF-8 octets. L'ancienne solution de contournement était btoa(unescape(encodeURIComponent(text))), ce qui prête à confusion mais fonctionne : encodeURIComponent encode en pourcentage UTF-8 octets, unescape reconvertit les triplets en caractères et btoa encode la chaîne binaire résultante. Cela fonctionne mais repose sur des fonctions obsolètes et est difficile à lire. Le code moderne doit utiliser TextEncoder(text).map(byte => String.fromCharCode(byte)) suivi de btoa, ou mieux, convertir directement en Uint8Array et utiliser l'API d'encodage.
Atob ne vous donne pas automatiquement de texte ; cela vous donne du binaire. atob(Y2Fmw6kg8J+YgA==) renvoie une chaîne binaire contenant les octets de texte codé UTF-8 avec accent caf et emoji. Pour récupérer le texte, convertissez la chaîne binaire en Uint8Array et transmettez-la à TextDecoder(utf-8). L'outil d'encodage et de décodage Base64 le fait automatiquement : vous collez du texte, il l'encode en UTF-8 octets, puis en base64. Les API Base64 à tableau typé évoluent à travers les navigateurs, mais cette source ne les utilise pas. Selon l'un d'entre eux, une vérification de compatibilité actuelle et un plan de secours sont nécessaires. La conversion explicite de tableau d'octets de ToolAcre reste inspectable et couverte par sa suite de tests actuelle.
Les alternatives aux tableaux typés évoluent : vérifiez la prise en charge actuelle du navigateur avant d'en dépendre
Vous collez base64, il décode en UTF-8 octets, puis en texte. L'étape intermédiaire de chaîne binaire est masquée car il s'agit d'un détail d'implémentation de l'API des années 1990. Comprendre atob et btoa est utile pour déboguer du code existant ou pour travailler avec d'anciennes API qui vous transmettent des chaînes binaires. La plupart des nouveaux codes devraient éviter complètement le modèle de chaîne binaire.
Si vous devez encoder ou décoder en base64, l'outil d'encodage et de décodage Base64 gère correctement Unicode. Si vous créez une API, acceptez Uint8Array ou une vue tableau typé, ou indiquez clairement si votre base64 est UTF-8 ou Latin-1. Lors de la révision du code qui utilise btoa avec du texte non-ASCII sans TextEncoder, il s'agit d'un bug : la sortie code les mauvais octets. Node Buffer et les environnements d'exécution sans navigateur définissent différentes API et règles d'acceptation. Ils sont intentionnellement exclus. Les revendications contenues dans cet article concernent les primitives du navigateur et le wrapper implémenté dans apps/dev, et non toutes les fonctions nommées atob ou btoa dans chaque environnement.
À retenir : deux fonctions des années 1990 avec un contrat de chaîne d'octets - comment l'encodeur et le décodeur Base64 font le UTF-8 les contourner pour que les accents, CJK et emoji aller-retour
Les noms atob et btoa sont des artefacts particuliers de l'informatique des années 1990. La dénomination moderne serait base64Encode et base64Decode, et les API accepteraient Uint8Array ou des chaînes avec des déclarations de codage explicites. Mais atob et btoa persistent dans les navigateurs pour des raisons de compatibilité ascendante. Comprendre ce qu'ils signifient (et ce qu'ils ne peuvent pas faire) vous aide à éviter une corruption silencieuse lors de l'encodage de texte Unicode.
L'outil d'encodage et de décodage Base64 comble le fossé : il parle les langages UTF-8 et base64 dont le code moderne a besoin. Le modèle robuste est compositionnel : codez le texte en UTF-8 octets, convertissez les octets en contrat de chaîne binaire, puis appelez btoa ; inversez ces étapes autour d'Atob. Essayez un accent, des caractères CJK et des emoji, puis demandez que le texte décodé corresponde à chaque point de code d'origine.