Saltar al contenido

Error al ejecutar ‘btoa’ en ‘Ventana’: El string a codificar contiene caracteres fuera del rango Latin1.

Luego de buscar en diversos repositorios y páginas al terminar hemos descubierto la resolución que te mostramos aquí.

Solución:

Si tiene UTF8, use esto (en realidad funciona con la fuente SVG), como:

btoa(unescape(encodeURIComponent(str)))

ejemplo:

 var imgsrc = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(markup)));
 var img = new Image(1, 1); // width, height values are optional params 
 img.src = imgsrc;

Si necesita decodificar esa base64, use esto:

var str2 = decodeURIComponent(escape(window.atob(b64)));
console.log(str2);

Ejemplo:

var str = "äöüÄÖÜçéèñ";
var b64 = window.btoa(unescape(encodeURIComponent(str)))
console.log(b64);

var str2 = decodeURIComponent(escape(window.atob(b64)));
console.log(str2);

Nota: si necesita que esto funcione en mobile-safari, es posible que deba eliminar todo el espacio en blanco de los datos base64 …

function b64_to_utf8( str ) 
    str = str.replace(/s/g, '');    
    return decodeURIComponent(escape(window.atob( str )));


Actualización 2017

Este problema me ha estado molestando nuevamente.
La simple verdad es que atob realmente no maneja cadenas UTF8, es solo ASCII.
Además, no usaría bloatware como js-base64.
Pero webtoolkit tiene una implementación pequeña, agradable y muy fácil de mantener:

/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info
*
**/
var Base64 = 

    // private property
    _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="

    // public method for encoding
    , encode: function (input)
    
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;

        input = Base64._utf8_encode(input);

        while (i < input.length)
         (chr3 >> 6);
            enc4 = chr3 & 63;

            if (isNaN(chr2))
            
                enc3 = enc4 = 64;
            
            else if (isNaN(chr3))
            
                enc4 = 64;
            

            output = output +
                this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
                this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
         // Whend 

        return output;
     // End Function encode 


    // public method for decoding
    ,decode: function (input)
    
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;

        input = input.replace(/[^A-Za-z0-9+/=]/g, "");
        while (i < input.length)
         (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4)  // Whend 

        output = Base64._utf8_decode(output);

        return output;
     // End Function decode 


    // private method for UTF-8 encoding
    ,_utf8_encode: function (string)
    
        var utftext = "";
        string = string.replace(/rn/g, "n");

        for (var n = 0; n < string.length; n++)
        
            var c = string.charCodeAt(n);

            if (c < 128)
            
                utftext += String.fromCharCode(c);
            
            else if ((c > 127) && (c < 2048))
            
                utftext += String.fromCharCode((c >> 6) 
            else
            
                utftext += String.fromCharCode((c >> 12) 

         // Next n 

        return utftext;
     // End Function _utf8_encode 

    // private method for UTF-8 decoding
    ,_utf8_decode: function (utftext)
    
        var string = "";
        var i = 0;
        var c, c1, c2, c3;
        c = c1 = c2 = 0;

        while (i < utftext.length)
        
            c = utftext.charCodeAt(i);

            if (c < 128)
            
                string += String.fromCharCode(c);
                i++;
            
            else if ((c > 191) && (c < 224))
             (c2 & 63));
                i += 2;
            
            else
            
                c2 = utftext.charCodeAt(i + 1);
                c3 = utftext.charCodeAt(i + 2);
                string += String.fromCharCode(((c & 15) << 12) 

         // Whend 

        return string;
     // End Function _utf8_decode 


https://www.fileformat.info/info/unicode/utf8.htm

  • Para cualquier carácter igual o inferior a 127 (hexadecimal 0x7F), la representación UTF-8 es un byte. Son solo los 7 bits más bajos del valor Unicode completo. Este también es el mismo que el valor ASCII.

  • Para caracteres iguales o inferiores a 2047 (hexadecimal 0x07FF), la representación UTF-8 se distribuye en dos bytes. El primer byte tendrá los dos bits altos configurados y el tercer bit se borrará (es decir, 0xC2 a 0xDF). El segundo byte tendrá el bit superior establecido y el segundo bit limpio (es decir, 0x80 a 0xBF).

  • Para todos los caracteres iguales o mayores que 2048 pero menores que 65535 (0xFFFF), la representación UTF-8 se distribuye en tres bytes.

Use una biblioteca en su lugar

No tenemos que reinventar la rueda. Simplemente use una biblioteca para ahorrar tiempo y dolores de cabeza.

js-base64

https://github.com/dankogai/js-base64 es bueno y confirmo que es compatible con Unicode muy bien.

Base64.encode('dankogai');  // ZGFua29nYWk=
Base64.encode('小飼弾');    // 5bCP6aO85by+
Base64.encodeURI('小飼弾'); // 5bCP6aO85by-

Base64.decode('ZGFua29nYWk=');  // dankogai
Base64.decode('5bCP6aO85by+');  // 小飼弾
// note .decodeURI() is unnecessary since it accepts both flavors
Base64.decode('5bCP6aO85by-');  // 小飼弾

Utilizando btoa con unescape y encodeURIComponent no funcionó para mí. Reemplazar todos los caracteres especiales con entidades XML / HTML y luego convertir a la representación base64 fue la única forma de resolver este problema para mí. Algún código:

base64 = btoa(str.replace(/[u00A0-u2666]/g, function(c) 
    return '&#' + c.charCodeAt(0) + ';';
));

Tienes la opción de añadir valor a nuestro contenido informacional añadiendo tu veteranía en las observaciones.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *