Maison  >  Article  >  interface Web  >  Comment décoder les chaînes UTF-8 base64 en JavaScript à l'aide d'atob tout en évitant les erreurs d'encodage ?

Comment décoder les chaînes UTF-8 base64 en JavaScript à l'aide d'atob tout en évitant les erreurs d'encodage ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-10-31 21:08:291000parcourir

How do you decode UTF-8 base64 strings in JavaScript using `atob` while avoiding encoding errors?

Utilisation d'atob pour décoder la base64 à partir de sources de texte courantes

Lorsque vous utilisez atob pour décoder les chaînes de réponse API des services qui génèrent leur sortie en UTF-8, vous pouvez rencontrer des erreurs ou des encodages de chaînes cassés. Cela est dû aux limitations de la gestion base64 de JavaScript :

<code class="js">const notOK = "✓"
console.log(btoa(notOK)); // error</code>

Le problème Unicode

Même après que cette erreur ait été résolue dans ECMAScript, le « problème Unicode » demeure, car base64 est un binaire format qui suppose que chaque caractère codé occupe un seul octet. De nombreux caractères Unicode nécessitent plus d'un octet pour être encodés, ce qui peut entraîner des échecs d'encodage.

Source : MDN (2021)

<code class="js">const ok = "a";
console.log(ok.codePointAt(0).toString(16)); // 0x61: occupies 1 byte

const notOK = "✓";
console.log(notOK.codePointAt(0).toString(16)); // 0x2713: occupies 2 bytes</code>

Solution avec interopérabilité binaire

Si vous ne savez pas quelle solution choisir, c'est probablement celle que vous souhaitez. Continuez à faire défiler la page pour trouver la solution ASCII base64 et l'historique de cette réponse.

Envisagez d'utiliser une approche binaire en convertissant les chaînes UTF-8 en représentations binaires et vice versa.

Encodage UTF-8 ⇢ binaire

<code class="js">function toBinary(string) {
  const codeUnits = new Uint16Array(string.length);
  for (let i = 0; i < codeUnits.length; i++) {
    codeUnits[i] = string.charCodeAt(i);
  }
  return btoa(String.fromCharCode(...new Uint8Array(codeUnits.buffer)));
}
encoded = toBinary("✓ à la mode") // "EycgAOAAIABsAGEAIABtAG8AZABlAA=="</code>

Décodage binaire ⇢ UTF-8

<code class="js">function fromBinary(encoded) {
  const binary = atob(encoded);
  const bytes = new Uint8Array(binary.length);
  for (let i = 0; i < bytes.length; i++) {
    bytes[i] = binary.charCodeAt(i);
  }
  return String.fromCharCode(...new Uint16Array(bytes.buffer));
}
decoded = fromBinary(encoded) // "✓ à la mode"</code>

Solution avec interopérabilité ASCII base64

Pour préserver la fonctionnalité UTF-8, une autre approche à travers L'interopérabilité ASCII base64 est recommandée, ce qui résout "Le problème Unicode" tout en maintenant la compatibilité avec les chaînes texte base64.

Encodage UTF-8 ⇢ ASCII base64

<code class="js">function b64EncodeUnicode(str) {
    // Percent-encode Unicode, then convert to byte array
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
        function(match, p1) {
            return String.fromCharCode('0x' + p1);
    }));
}
b64EncodeUnicode('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="</code>

Décodage ASCII base64 ⇢ UTF -8

<code class="js">function b64DecodeUnicode(str) {
    // Convert byte array to percent-encoding, then decode
    return decodeURIComponent(atob(str).split('').map(function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    }).join(''));
}
b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"</code>

Prise en charge de TypeScript

<code class="ts">function b64EncodeUnicode(str) {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
        return String.fromCharCode(parseInt(p1, 16))
    }))
}
function b64DecodeUnicode(str) {
    return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
    }).join(''))
}</code>

Notes supplémentaires

  • La suppression des espaces blancs peut être nécessaire pour décoder les chaînes base64 à partir de sources telles que l'API GitHub sur Safari.
  • Les bibliothèques comme js-base64 et base64-js fournissent également des solutions fiables.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn