问题描述
我在一个项目中使用Ace Editor,我想知道如何运行用户输入到编辑器中的代码。我以为我可以使用这样的东西:
var editor = ace.edit("editor");
editor.setTheme("ace/theme/chaos");
editor.session.setMode("ace/mode/javascript");
function runProgram() {
var code = editor.getValue();
var display = document.getElementById("display");
try {
var result = eval(code);
display.innerHTML = result;
} catch(e) {
alert('Error' + e);
}
}
但是出于安全性考虑,我不确定要使用eval()
。我希望找到某种方法来安全地执行和显示用户代码。请注意,我是javascript的初学者。
解决方法
如果要在同一用户上运行用户编写的代码,则不必担心计算机安全性,因为用户可以在浏览器控制台中运行相同的代码。
但是,如果要防止用户意外破坏编辑器,可以使用具有沙箱属性和适当CORS策略的iframe。如果您从其他域加载iframe,它将在chrome中以其他进程运行,并且无限循环不会阻塞编辑器。
这将是一个玩具实现
iframe = document.body.appendChild(document.createElement("iframe"))
iframe.sandbox="allow-modals allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts"
iframe.src="data:text/html," + encodeURIComponent(`<script>
function runProgram(e) {
console.log(e)
var code = e.data;
var display = document.body;
try {
var result = eval(code);
display.innerHTML = result;
} catch(e) {
alert('Error' + e);
}
}
window.onmessage = runProgram</script>
waiting...`)
然后,当用户按下运行按钮时,请使用postMessage。
iframe.contentWindow.postMessage(editor.getValue(),"*")
实际的实现要复杂得多,例如,https://github.com/jsbin/jsbin对于执行此类操作的受欢迎的开源项目而言。