Hello!
Depending on the development state of your project I would advise against ruling out solutions that work but might have some drawbacks. Often it is better to get something running and optimise it afterwards than to not getting anything to work because of such concerns.
Also, a system is considered safe from being hacked if the cost of hacking it is greater than the gain an attacker would get out of it. Your app can always be target of memory manipulation from things like cheat engine - especially within the web.
So unless you are creating a system that has to be super secure I am sure you won't be having issues with the JS implementation.
Now to the code. I did not make an MVP project for this but this code should get you going:
var _callback = JavaScript.create_callback(self, "receivedMessage")
func _ready():
subToMessages()
func subToMessages():
if OS.has_feature('JavaScript'):
var window = JavaScript.get_interface("window")
window.onmessage = _callback
func receivedMessage(args):
# parse
var key
if args[0].message:
key = 'message'
else:
key = 'data'
var data = args[0][key]
# filter
if data.find('toGodot:') == 0:
# message starts with 'toGodot:'
data = data.replace('toGodot:', '')
# emit or whatever you wanna do with this data
emit_signal('message', data)
you can test if this works by calling this in JS (make sure to replace the URL):
postMessage('toGodot:test','http://127.0.0.1:5500')
The "toGodot" part of the code is just to filter out any messages that might be sent that are not intended for the Godot application. For an MVP this would not be required but it surely doesn't harm the integrity aspect.
Edit: On the JS front where you probably have the app integrated via an iframe you call things like
var iframe = document.getElementsByTagName("iframe")[0]
var gdBase = 'toGodot:'
iframe.contentWindow.postMessage(gdBase + 'scroll:' + offset / max * 100, 'https://your.url.com')
2nd Edit: If you want to send data from Godot to JS you can use this code. Now you have a bidirectional instant communication setup:
func postMessage(data, iframe = false, target = "https://your.url.com/"):
if OS.has_feature('JavaScript'):
if iframe:
return JavaScript.eval("""
window.parent.postMessage('""" + data + """', '""" + target + """')
""")
else:
# message receiver might change if this features is used in android as well
return JavaScript.eval("""
postMessage('""" + data + """', '""" + target + """')
""")
return null
Let me know if this works. Could be that i missed some code when copying it all together.