xhr responsetype javascript html5 websocket blob filereader

javascript - xhr - responsetype header



Mostrar imagen de blob usando javascript y websockets (5)

Actualmente estoy trabajando en una aplicación WebSocket que muestra imágenes enviadas por un servidor C ++. He visto un par de temas por ahí pero parece que no puedo deshacerme de este error en Firefox:

Imagen dañada o truncada: datos: imagen / png; base64, [algunos datos]

Aquí está el código Javascript que estoy usando para mostrar mi blob:

socket.onmessage = function(msg) { var blob = msg.data; var reader = new FileReader(); reader.onloadend = function() { var string = reader.result; var buffer = Base64.encode(string); var data = "data:image/png;base64,"+buffer; var image = document.getElementById(''image''); image.src = data; }; reader.readAsBinaryString(blob); }

Estoy usando la imagen de un punto rojo que encontré en este tema: https://stackoverflow.com/a/4478878/1464608 Y la clase Base64 es de aquí: https://stackoverflow.com/a/246813/1464608

Pero el resultado de la base64 que obtengo no coincide y Firefox me recupera un error de la imagen dañada.

Sé que esto no es mucha información, pero no tengo ni idea de dónde buscar: / ¡Cualquier ayuda es más que bienvenida!


Creo que la solución más limpia sería cambiar el codificador base64 para que funcione directamente en un Uint8Array en lugar de una cadena.

Importante: para ello deberá establecer el tipo binario del socket web en "arraybuffer".

El método onmessage debería verse así:

socket.onmessage = function(msg) { var arrayBuffer = msg.data; var bytes = new Uint8Array(arrayBuffer); var image = document.getElementById(''image''); image.src = ''data:image/png;base64,''+encode(bytes); };

El codificador convertido debería tener este aspecto (basado en https://.com/a/246813/1464608 ):

// public method for encoding an Uint8Array to base64 function encode (input) { var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; var output = ""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; while (i < input.length) { chr1 = input[i++]; chr2 = i < input.length ? input[i++] : Number.NaN; // Not sure if the index chr3 = i < input.length ? input[i++] : Number.NaN; // checks are needed here enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output += keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4); } return output; }


Gracias a las otras respuestas, logré recibir una imagen jpeg por websocket y mostrarla en una nueva ventana:

socket.binaryType = "arraybuffer"; socket.onmessage = function (msg) { var bytes = new Uint8Array(msg.data); var blob = new Blob([bytes.buffer]); window.open(URL.createObjectURL(blob),''Name'',''resizable=1''); };


Gracias, está funcionando muy bien !!

Así que imagino que compartiría mi código javascript final:

var socket = new WebSocket(''ws://''+host+'':''+port, protocol); socket.binaryType = ''arraybuffer''; try { socket.onopen = function() { document.getElementById(''status'').style.backgroundColor = ''#40ff40''; document.getElementById(''status'').textContent = ''Connection opened''; } socket.onmessage = function(msg) { var arrayBuffer = msg.data; var bytes = new Uint8Array(arrayBuffer); var image = document.getElementById(''image''); image.src = ''data:image/png;base64,''+encode(bytes); } socket.onclose = function(){ document.getElementById(''status'').style.backgroundColor = ''#ff4040''; document.getElementById(''status'').textContent = ''Connection closed''; } } catch(exception) { alert(''Error:''+exception); }

realmente no entiendo por qué la versión de blob es tan complicada, ¡pero esto hizo el truco!


Otra alternativa

let urlObject; socket.onmessage = function(msg) { const arrayBuffer = msg.data; const image = document.getElementById(''image''); if (urlObject) { URL.revokeObjectURL(urlObject) // only required if you do that multiple times } urlObject = URL.createObjectURL(new Blob([arrayBuffer])); image.src = urlObject; };


Puedes escribirlo mucho más simple:

socket.onmessage = function(msg) { var arrayBuffer = msg.data; var bytes = new Uint8Array(arrayBuffer); var blob = new Blob([bytes.buffer]); var image = document.getElementById(''image''); var reader = new FileReader(); reader.onload = function(e) { image.src = e.target.result; }; reader.readAsDataURL(blob); };