Godot调用JavaScript.eval()无法弹出文件选择框 是代码还是引擎问题
问题根因
- 浏览器安全策略限制:现代浏览器均禁止非用户主动交互触发的文件选择弹窗,
input.click()调用必须直接嵌套在用户交互事件(点击、触屏、键盘按下等)的同步执行栈中,异步调用、定时触发、非交互场景调用都会被直接拦截,且不会抛出可见报错。 - Godot执行时机问题:若你调用
JavaScript.eval()的时机并非直接对应原生用户交互事件的同步回调(例如在_process生命周期中调用、异步等待后调用、或在Godot输入事件回调中添加await后再调用),都会导致JS代码执行脱离用户交互同步栈,触发浏览器拦截规则。
解决方案
首先调整调用逻辑,将JS执行逻辑直接绑定在用户交互的同步回调中,参考GDScript示例:
# 绑定到按钮的pressed信号、或InputEventMouseButton的直接处理逻辑中 func _on_file_import_button_pressed() -> void: # 回调内不要添加任何await、延迟类逻辑,保证JS代码同步执行 JavaScript.eval(""" const input = document.createElement("input"); input.type = "file"; input.accept = ".txt,.json"; // 可按需限制可选文件类型 input.onchange = (e) => { // 此处编写文件选中后的处理逻辑 const selectedFile = e.target.files[0]; console.log("选中文件:", selectedFile.name); // 如需回传文件内容到Godot,可在此处调用你预先暴露的Godot方法 }; input.click(); """)
额外注意事项:
- 无需将创建的
input元素挂载到document.body,该操作非必要,反而可能导致Godot画布焦点丢失。 - 不要直接在本地打开导出的HTML文件测试,必须通过HTTP服务器托管访问,本地文件协议的安全限制会拦截文件选择操作。
- 若仍无法触发,检查Web导出配置,确认未添加会禁止动态DOM操作的自定义内容安全策略(CSP)规则。
内容的提问来源于stack exchange,提问作者Jude Lingan
相关产品推荐
相关产品推荐

