gpt4 book ai didi

javascript - 如何评估我的 Web 应用程序中的用户代码输入

转载 作者:行者123 更新时间:2023-11-30 12:11:58 25 4
gpt4 key购买 nike

我正在尝试构建一个演示站点来帮助其他人学习编码。我在评估用户从代码输入时遇到问题。我知道我可以使用 eval() 函数,但我会举出很多例子,而且有很多 eval() 函数似乎不是最佳选择或简洁的。如果我要使用 eval(),那么最佳实践的最佳实现方式是什么?

或者,有没有一种方法可以实现一个简单的编译器或一个通用函数,并分配一个按钮单击以运行所述函数,该函数将在编辑器中评估代码并将其显示在页面上的某个位置。

我目前正在使用 Ace给我的编辑。也许他们的 api 中有一个函数可以执行此操作,但我找不到它。我也知道我可以使用代码镜像,但也不确定他们的解决方案。任何帮助将不胜感激。

Here是 JSBIN 的链接(注意:代码编辑器不会显示在这里,因为我不需要库。

Here是指向我拥有功能版本的网站的链接。

如果您需要查看我在下面发布的代码:

HTML

    <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Learn to Code with Codesmith</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400;300' rel='stylesheet' type='text/css'>
<link href='style.css' rel='stylesheet'>
<style type="text/css" media="screen">

</style>
</head>
<body>

<!-- <div class="page-wrapper">
<a class="btn trigger" href="javascript:;">Click Me!</a>
</div> -->
<div class="modal-wrapper">
<div class="modal">
<div class="head">
<a class="btn-close trigger" href="javascript:;"></a>
</div>
<div class="content">
<form class="" action="" method="post">
<input id="username" type="text" name="name" value="" placeholder="Username">
<input id="password" type="text" name="name" value="" placeholder="Password">
<button id="login-submit" type="button" name="button">LOGIN</button>
</form>
</div>
</div>
</div>

<div class="menu">

<!-- Menu icon -->
<div class="icon-close">
<img src="http://s3.amazonaws.com/codecademy-content/courses/ltp2/img/uber/close.png">
</div>

<!-- Menu -->
<ul>
<li class="main-cat"><a href="#">FOUNDATIONS</a></li>
<ul>
<li class="sub-cat"><a href="#">Intro to Javascript</a></li>
<li class="sub-cat"><a href="#">Algorithms</a></li>
<li class="sub-cat"><a href="#">Data Structures</a></li>
<li class="sub-cat"><a href="#">Data Types</a></li>
<li class="sub-cat"><a href="#">Syntax</a></li>
<li class="sub-cat"><a href="#">Variables</a></li>
<li class="sub-cat"><a href="#">Strings</a></li>
<li class="sub-cat"><a href="#">Arrays</a></li>
<li class="sub-cat"><a href="#">Objects</a></li>
<li class="sub-cat"><a href="#">Functions</a></li>
<li class="sub-cat"><a href="#">Scope</a></li>
</ul>
<li class="main-cat"><a href="#">Intermediate</a></li>
<li class="main-cat"><a href="#">Advanced</a></li>

</ul>
</div>



<!-- Main body -->
<div class="nav">

<button class="sign-up" type="button" name="button" onclick="">SIGN UP</button>

<!-- <a class="btn trigger" href="javascript:;">Click Me!</a> -->
<!-- <button class="login trigger" type="button" name="button" onclick="">LOGIN</button> -->
<a class="login trigger" type="button" name="button" onclick="" href="javascript:;">LOGIN</a>

<div class="icon-menu">
<i class="fa fa-bars"></i>
Menu
</div>

<div class="video">
<iframe width="560" height="315" src="https://www.youtube.com/embed/JeyH_8pWVJ4" frameborder="0" allowfullscreen></iframe>
</div>

<div class="code-snippet sandbox">
<pre id="editor"> // Write your code here and when finished, click the run button below...
<!-- function greeting() {
console.log("Hello, World!");
} -->
</pre>



<div id="run-code">
<button class="run-code" type="button" name="button" onclick="evaluate()" >RUN</button>
</div>
</div>

<!-- <textarea class="code-eval" name="output" rows="8" cols="40"></textarea> -->


<!-- <a class="jsbin-embed" href="http://jsbin.com/iwovaj/73/embed?html,output&height=315px&width=700px"></a>
<script src="http://static.jsbin.com/js/embed.js"></script> -->

<script src="src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
var editor = ace.edit("editor");
editor.setTheme("ace/theme/chaos");
editor.session.setMode("ace/mode/javascript");
editor.session.getLength(true);
document.getElementById('editor').style.fontSize='14px';
editor.getSession().setUseWrapMode(true);
editor.setHighlightActiveLine(true);
</script>
<script src="sandbox.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script></script>
<script src="app.js"></script>
</body>
</html>

CSS

html, body{
width:100%;
height:100%;
margin:0;
}

body {
overflow: hidden;
left: 0;
margin: 0;
overflow: hidden;
position: relative;
}
#editor {
margin: 0;
position: relative;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 700px;
height: 315px;
}
.code-snippet {
margin:0 auto;
display: block;
float: right;
padding: 40px 40px;

}

.run-code {
background-color: #1fbad6;
border: 3px solid #1fbad6;
padding: 10px 20px;
margin-top: 40px;
margin-bottom: 40px;
outline: none;
font:1.125em 'Arial', sans-serif;
font-weight:700;
text-align:center;
text-decoration:none;
color:#fff;
border-radius:5px;
float: right;
}

.video {
position: relative;
float: left;
padding: 40px 40px;
}
/*.jsbin-embed {
position: relative;
float: right;
width: 700px;
height: 315px;
padding: 40px 40px;
}*/

/* Initial menu */
.menu {
background: #202024 url('http://s3.amazonaws.com/codecademy-content/courses/ltp2/img/uber/black-thread.png') repeat left top;
left: -285px; /* start off behind the scenes */
height: 100%;
position: fixed;
width: 285px;
}

/* Basic styling */

.nav {
/*background-image: url('http://s3.amazonaws.com/codecademy-content/courses/ltp2/img/uber/bg.png');*/
background-color: #202020;
height: 75px;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}

.menu ul {
border-top: 1px solid #636366;
list-style: none;
margin: 0;
padding: 0;
}

.menu li {
font-family: 'Open Sans', sans-serif;
line-height: 45px;
padding-bottom: 3px;
padding-left: 20px;
padding-top: 3px;
}

.main-cat {
border-bottom: 1px solid #636366;
color: #03A3EA;
}

.sub-cat li {
font-family: 'Open Sans', sans-serif;
line-height: 45px;
padding-bottom: 3px;
padding-left: 20px;
padding-top: 3px;
}

.menu a {
color: #fff;
font-size: 15px;
text-decoration: none;
text-transform: uppercase;
}

.icon-close {
cursor: pointer;
padding-left: 10px;
padding-top: 10px;
}

.icon-menu {
color: #1fbad6;
cursor: pointer;
font-family: 'Open Sans', sans-serif;
font-size: 20px;
padding-bottom: 25px;
padding-left: 25px;
padding-top: 25px;
text-decoration: none;
text-transform: uppercase;
}

.icon-menu i {
margin-right: 5px;
}

.login {
position: relative;
float: right;
margin-top: 18px;
margin-right: 20px;
padding: 5px 15px;
font-size: 18px;
color: #1fbad6;
background: none;
border: 3px solid #1fbad6;
font:1.125em 'Arial', sans-serif;
font-weight:700;
text-align:center;
text-decoration:none;
border-radius:5px;
}

.sign-up {
position: relative;
float: right;
margin-top: 18px;
margin-right: 20px;
padding: 5px 15px;
font-size: 18px;
color: #1fbad6;
background: none;
border: 3px solid #1fbad6;
font:1.125em 'Arial', sans-serif;
font-weight:700;
text-align:center;
text-decoration:none;
border-radius:5px;
}


/* ============ MODAL ========== */


.page-wrapper{
width:100%;
height: 100%;
/* //background:url(http://i.imgur.com/2ZgHKbQ.jpg) center no-repeat;
//background-size:cover;*/
}

.blur{
-webkit-filter: blur(5px);
-moz-filter: blur(5px);
-o-filter: blur(5px);
-ms-filter: blur(5px);
filter: blur(5px);
}

a.btn{
width:150px;
display:block;
margin:-25px 0 0 -75px;
padding:1em 0;
position:absolute;
top:50%; left:50%;
font:1.125em 'Arial', sans-serif;
font-weight:700;
text-align:center;
text-decoration:none;
color:#fff;
border-radius:5px;
background:rgba(217,67,86,1);
}

.modal-wrapper{
width:100%;
height:100%;
position:fixed;
top:0; left:0;
background:rgba(64,64,64,1);
visibility:hidden;
opacity:0;
-webkit-transition: all 0.25s ease-in-out;
-moz-transition: all 0.25s ease-in-out;
-o-transition: all 0.25s ease-in-out;
transition: all 0.25s ease-in-out;
z-index: 999;
}

.modal-wrapper.open{
opacity:1;
visibility:visible;
}

.modal{
width:600px;
height:400px;
display:block;
margin:50% 0 0 -300px;
position:relative;
top:50%; left:50%;
background:#fff;
opacity:0;
-webkit-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
}

.modal-wrapper.open .modal{
margin-top:-200px;
opacity:1;
}

.head{
width:90%;
height:32px;
padding:1.5em 5%;
overflow:hidden;
background:#01bce5;
}

.btn-close{
width:32px;
height:32px;
display:block;
float:right;
}

.btn-close::before, .btn-close::after{
content:'';
width:32px;
height:6px;
display:block;
background:#fff;
}

.btn-close::before{
margin-top:12px;
-webkit-transform:rotate(45deg);
-moz-transform:rotate(45deg);
-o-transform:rotate(45deg);
transform:rotate(45deg);
}

.btn-close::after{
margin-top:-6px;
-webkit-transform:rotate(-45deg);
-moz-transform:rotate(-45deg);
-o-transform:rotate(-45deg);
transform:rotate(-45deg);
}

.content{
padding:5%;
}

#username {
width: 95%;
background: none;
border: 3px solid #1fbad6;
padding: 12px;
margin-bottom: 40px;
outline: none;
font:1.125em 'Arial', sans-serif;
font-weight:700;
text-decoration:none;
border-radius:5px;
color: #202020;
}

#password {
width: 95%;
background: none;
border: 3px solid #1fbad6;
padding: 12px;
margin-bottom: 40px;
outline: none;
font:1.125em 'Arial', sans-serif;
font-weight:700;
text-decoration:none;
border-radius:5px;
color: #202020;
}

#login-submit {
background-color: #1fbad6;
border: 3px solid #1fbad6;
padding: 10px 20px;
margin-bottom: 40px;
outline: none;
font:1.125em 'Arial', sans-serif;
font-weight:700;
text-align:center;
text-decoration:none;
color:#fff;
border-radius:5px;
float: right;
}

JavaScript

var main = function() {
/* Push the body and the nav over by 285px over */
$('.icon-menu').click(function() {
$('.menu').animate({
left: "0px"
}, 100);

$('body').animate({
left: "285px"
}, 100);
});

/* Then push them back */
$('.icon-close').click(function() {
$('.menu').animate({
left: "-285px"
}, 100);

$('body').animate({
left: "0px"
}, 100);
});
};


/* ========== Evaluate Code ========== */

var app = {};

// go through the application and find every single instance of a div
// with the class of 'sandbox'
app.bootstrap = function() {
var sandboxes = document.getElementsByClassName('sandbox');

// for each sandbox, run the createSandbox function
[].forEach.call(sandboxes, app.createSandbox);
};

// given a parent element, find the first textarea inside and
// create a sandbox around it
app.createSandbox = function(parent) {
var textarea = parent.getElementsByTagName('textarea')[0],
// create an instance of Sandbox using this textarea
sandbox = Sandbox(textarea);

parent.appendChild(sandbox.label);
};

// when the DOM loads bootstrap the application
window.addEventListener('load', app.bootstrap);

// Sandbox class
// This class is based around a textarea element, which will contain
// the code. However, it could just as easily be the DOM element for
// an Ace/Codemirror editor.
function Sandbox(textarea) {
var sandbox = {};

// create a label to show output
sandbox.label = document.createElement('label');
sandbox.label.setAttribute('class', 'output');
sandbox.label.addEventListener('click', evaluate);

// evaluate code whenever there is input into the textarea
textarea.addEventListener('input', evaluate);
sandbox.textarea = textarea;

// initial resize and evaluation
resize();
evaluate();

// resize to within the appropriate height for the textarea
function resize() {
var scrollHeight = textarea.scrollHeight;

if(scrollHeight > Sandbox.MAX_HEIGHT) {
height = Sandbox.MAX_HEIGHT;
} else if(scrollHeight < Sandbox.MIN_HEIGHT) {
height = Sandbox.MIN_HEIGHT;
} else {
height = scrollHeight;
}

textarea.style.height = height + 'px';
}

// evaluate the code within the textarea
function evaluate() {
// get the code
var src = textarea.value,
// create a console proxy (for logging to the label)
console = Sandbox.consoleProxy(sandbox.label);

// clear the output first
sandbox.label.innerText = '';
// try the eval and catch errors to send to the console
try {
/* jshint ignore:start */
eval(src);
/* jshint ignore:end */
} catch(err) {
console.error(err);
}
}

return sandbox;
}

// config
Sandbox.MAX_HEIGHT = 500;
Sandbox.MIN_HEIGHT = 50;

// A function which spoofs the native console object, by writing
// text to output elements, rather than the dev tools console.
Sandbox.consoleProxy = function(element) {
return {
log: function(message) {
message = [].join.call(arguments, ' ');
element.innerText += (message + '\n');
element.setAttribute('disabled', false);
// write to the original console too
console.log.apply(console, arguments);
},
error: function(message) {
element.setAttribute('disabled', true);
element.innerText = message;
}
};
};


/* ========== Modal ========== */

$('.trigger').click(function() {
$('.modal-wrapper').toggleClass('open');
$('.page-wrapper').toggleClass('blur');
return false;
});

$(document).ready(main);

最佳答案

eval是运行代码的实际方式。由于与安全漏洞有关,它的名声不太好,但是,如果这不是问题并且用户将在沙箱中运行他们自己的代码,那正是 eval旨在做到这一点,而且做得很好。

为 Javascript 实现一个简单的编译器并非易事,但是如果您确信这是正确的方法,您可以使用开源项目,例如 esprima。在解析和评估代码时为您完成一些繁重的工作。

我为过去从事的项目开发了一个通用代码评估小部件,只需使用 <textarea>eval .它支持控制台的日志和错误沙盒。浏览 the code 可能会有所帮助.

关于javascript - 如何评估我的 Web 应用程序中的用户代码输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33507292/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com