Transfer binary data (maybe blob) between parent_html and godot_app

Godot Version

Godot_v4.2.2-stable_linux.x86_64

Question

I have this code (in js and maybe it is wrong) to send a blob from the parent html to godot iframe:

			document.getElementById("button_send_image").addEventListener("click", function () {
								const tuxImage = "https://upload.wikimedia.org/wikipedia/commons/5/56/Tux.jpg";
				fetch(tuxImage)
					.then(response => response.blob())
					.then(blob => {
						blob.arrayBuffer().then( arrayBuffer => {
							// origin is for avoid the messages from browser plugins (as angular dev plugin).
							const message = {'origin': 'parent', 'data': 'image', 'image': new Uint8Array(arrayBuffer)};
							console.log(message);
							
							const iframe = document.getElementById("iframe");
							// Transfer port1 to the iframe
							channel.port1.postMessage(message);
						});
					});
			});

But from the godot app (exported as web) I can not get image, this is the code to get image:

extends Control

var console = JavaScriptBridge.get_interface("console")
var JSON_js = JavaScriptBridge.get_interface("JSON")
var messageListenerCallback = JavaScriptBridge.create_callback(messageListener)

var portJS : JavaScriptObject

# Called when the node enters the scene tree for the first time.
func _ready():
	$Label.text = OS.get_name()
	if OS.has_feature('web'):
		console.log("ES WEB");
		JavaScriptBridge.get_interface("window").addEventListener('message', messageListenerCallback)


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	pass
	
func messageListener(args) -> void:
	var js_event = args[0]
	if (js_event.data.origin == 'parent'):
		match js_event.data.data:
			"init" :
				var message = JSON_js.parse(JSON.stringify({'origin': 'iframe', 'data': 'inited'}))
				print(message)
				console.log(message)
				portJS = js_event.ports[0]
				portJS.postMessage(message)
				
				portJS.onmessage = messageListenerCallback
			"image":
				 ## Crear una imagen
				var byte_array = js_event.data.image
				print("WHAT IS byte_array?")
				print(type_string(typeof(byte_array)))
				var temp: Dictionary = JSON.parse_string(JSON_js.stringify(byte_array))
				var packed_byte_array = PackedByteArray(temp.values())
				
				var image = Image.new()
				var error = image.load_jpg_from_buffer(packed_byte_array)
				if error == OK:
					var texture = ImageTexture.new()
					texture.create_from_image(image)
					print(texture)
					print(texture.get_format())
					print(texture.get_size())
					print(texture.get_width())
					## Asignar la textura al Sprite
					$test_image.texture = texture
				else:
					print("Error al cargar la imagen: ", error)
			_ :
				var data = JSON.parse_string(JSON_js.stringify(js_event.data.data))
				$message.text = data
				print(type_string(typeof(data)))
		print("Message")
		print(js_event.data.data)
		console.log(js_event.data)

Is there a method or code to transfer binary data (as blob for example) parent_html <—> godot_app_web?

Well, I found the problem, it was a bug from the type PEBCAK (and yes I was between keyboard and the chair).

I forget that json can store a complex types, and I assumed that a Uint8Array (js) in a json was automatic converted to array of numbers.

The solution is convert to base64 to store in the json (in js) and in Godot the reverse action base64->arraybuffer.

			document.getElementById("boton_enviar_imagen").addEventListener("click", function () {
								const tuxImage = "./img.bmp";
				fetch(tuxImage)
					.then(response => response.blob())
					.then(blob => {
						blob.arrayBuffer().then( arrayBuffer => {
							// origin is for avoid the messages from browser plugins (as angular dev plugin).
							const message = {'origin': 'parent', 'data': 'image', 'image': arrayBufferToBase64(arrayBuffer)};
							console.log("MESSAGE TO SEND", message);
							
							const iframe = document.getElementById("iframe");
							// Transfer port1 to the iframe
							channel.port1.postMessage(message);
						});
					});
			});

....

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

And in Godot is:

			"image":
				var received_img_base64: String = js_event.data.image
				var img = Image.new()
				var buffer: PackedByteArray = Marshalls.base64_to_raw(received_img_base64)
				print("SIZE buffer ", buffer.size())
				img.load_bmp_from_buffer(buffer)
				var texture: Texture = ImageTexture.create_from_image(img)
				$Icon.texture = texture
				$Icon.texture_filter = TEXTURE_FILTER_NEAREST