Convirtiendo arraybuffer a cadena: se excedió el tamaño máximo de la pila de llamadas

3 minutos de lectura

Avatar de usuario de Suresh Atta
Suresh atta

Este es mi código.

var xhr = new XMLHttpRequest();
xhr.open('GET',window.location.href, true);
xhr.responseType = "arraybuffer";
xhr.onload = function(event) {
 debugger;
 console.log(" coverting array buffer to string "); 
 alert(String.fromCharCode.apply(null, new Uint8Array(this.response)));
};
xhr.send();

Esa solicitud se realiza a una URL de PDF que tiene un tamaño de alrededor de 3 MB. He leído algunos hilos con el mismo error, Se excedió el número máximo de llamadas a la pila, diciéndome que debe haber alguna llamada recursiva pero no veo ninguna llamada recursiva aquí. ¿Alguien puede ayudar?

  • ¿Es esta solicitud a la misma página? Usando GET en window.location.href?

    – skobaljic

    18 de julio de 2016 a las 9:16

  • @skobaljic Sí. Por ejemplo, la página actual es cs.columbia.edu/~lok/3101/lectures/02-corejava.pdf

    – Suresh Atta

    18 de julio de 2016 a las 9:19

  • Si llama a la misma página con el mismo script incluido, ¿por qué se pregunta si hay demasiada recursividad? Intente llamar a otra página sin guión. O si llama a través de xhr, entonces no vuelva a generar el script o agregue un parámetro para diferenciar la llamada.

    – skobaljic

    18 de julio de 2016 a las 10:27


  • @skobaljic este script no se ejecutará en la función de carga. Solo estoy leyendo los datos de la página pdf.

    – Suresh Atta

    18 de julio de 2016 a las 10:29

  • ¿Has intentado cargar otra página, otro pdf?

    – skobaljic

    18/07/2016 a las 10:30


Tuve el mismo problema y finalmente usé este código:

function _arrayBufferToBase64( buffer ) {
    var binary = '';
    var bytes = new Uint8Array( buffer );
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode( bytes[ i ] );
    }
    return window.btoa( binary );
}

  • podría utilizar reduce en cambio, pero esto parece ser lo que es necesario

    – Garr Godofredo

    5 de noviembre de 2020 a las 18:24

  • esta debería ser la respuesta aceptada. Funciona de maravilla

    – siguiente

    11 de noviembre de 2020 a las 12:42

avatar de usuario de le_m
le_m

El error se debe a una limitación en el número de argumentos de la función. Consulte “RangeError: se excedió el tamaño máximo de la pila de llamadas” ¿Por qué?

En vez de String.fromCharCode.apply()utilice por ejemplo un TextEncoder. Ver Uint8Array a la cadena en Javascript

  • Hola. ¿Cómo usas el TextEncoder ¿en mi caso? tengo esto var base64 = btoa(String.fromCharCode.apply(null, new Uint8Array(blob)));

    – Desarrollador

    6 de marzo de 2018 a las 3:45

  • Abrí una pregunta aparte

    – Desarrollador

    6 de marzo de 2018 a las 5:01

  • Para una cadena binaria TextEncoder es inútil, no es compatible Latin1 (usa Windows−1252), obtendrá el resultado roto. (new TextDecoder("ISO-8859-1").decode(new Uint8Array([148]))).charCodeAt(0); // 8221, debería ser 148

    – KeyKi

    17/03/2020 a las 17:00

this.response.arrayBuffer()
              .then((buf) => {
                const uint8Array = new Uint8Array(buf);
                const data = uint8Array.reduce((acc, i) => acc += String.fromCharCode.apply(null, [i]), '');
                return data;
              })

Thank you so much Anthony O, you saved my 10 days work.
small modification in my scenario is:

Angular 7 :

/** Convert Uint8Array to string */

    private static arrayBufferToBase64( buffer: Uint8Array ) {
        var binary = '';
        var bytes = new Uint8Array( buffer );
        var len = bytes.byteLength;
        for (var i = 0; i < len; i++) {
            binary += String.fromCharCode( bytes[ i ] );
        }
        return  binary;
    }

¿Ha sido útil esta solución?