开发在线编程网站
前言
初學(xué)者學(xué)習(xí)編程語言時(shí),通常需要安裝編程語言對(duì)應(yīng)的環(huán)境,以Python為例,要學(xué)習(xí)Python,你就需要下載Python解釋器并安裝到本地,對(duì)于沒有編程經(jīng)驗(yàn)的人而言,這一步難倒了很多人,所以很多編程學(xué)習(xí)網(wǎng)站提供了在線編程的功能,學(xué)習(xí)者可以在網(wǎng)站上直接編寫Python代碼,然后點(diǎn)擊運(yùn)行,便可以在網(wǎng)頁中得到相應(yīng)的結(jié)果,這是怎么做到的?
最近剛好在做直播任務(wù),即每周要做一定量的抖音直播,昨日直播時(shí),臨時(shí)起意,打算實(shí)現(xiàn)這個(gè)功能并將查資料、研究、開發(fā)的過程作為直播內(nèi)容,開播時(shí),我也不知道自己能不能弄出來,但因?yàn)閯傋鲋辈]多久,沒啥人看,也就沒啥包袱,直接開整,最后還是讓我弄出來了。
本篇文章就記錄一下開發(fā)過程。
前端開發(fā)
經(jīng)過簡(jiǎn)單的調(diào)研,放棄一開始想用Vue3開發(fā)的想法,直接使用HTML、CSS、JS搞則可,再上個(gè)Jquery,來使用Ajax,大體的流程為:
Code?=>?Ajax?=>?Python?Web(Flask)?=>?Run?Code?=>?Result代碼通過Ajax發(fā)給后端服務(wù)(Flask構(gòu)建),不同編程語言使用不同的解釋器去執(zhí)行相應(yīng)的代碼,將執(zhí)行的結(jié)果返回。
創(chuàng)建online-ide的目錄,在目錄下,構(gòu)建如下結(jié)構(gòu):
C:\USERS\ADMIN\WORKPLACE\ONLINE-IDE ├─back-end├─serve.py └─front-end├─ide.html├─css└─style.css├─js└─ide.js└─libfront-end用于放前端代碼,back-end用于放后端代碼,我們將頁面的主代碼寫到ide.html中,代碼非常簡(jiǎn)單,就是用div構(gòu)建不同的部分,然后用css簡(jiǎn)單修飾一下:
<!DOCTYPE?html> <html?lang="en"> <head><meta?charset="UTF-8"><meta?http-equiv="X-UA-Compatible"?content="IE=edge"><meta?name="viewport"?content="width=device-width,?initial-scale=1.0"><title>Online?IDE</title><!--?<link?rel="stylesheet"?href="css/style.css"/>?--><link?rel="stylesheet"?href="front-end/css/style.css"> </head> <body><div?class="header">?Online?IDE?</div><div?class="control-panel"><!--?選擇編程語言?-->選擇編程語言: <select?name="languages"?id="languages"?class="languages"?onchange="changeLanguage()"><option?value="c">C</option><option?value="cpp">C++</option><option?value="nodejs">Node.js</option><option?value="python">Python</option></select></div><div?class="editor"?id="editor"><!--?編寫代碼的地方?--></div><div?class="button-container"><!--?點(diǎn)擊按鈕,運(yùn)行代碼?--><button?class="btn"?onclick="runCode()">?運(yùn)行?</button></div><div?class="output"><!--?代碼結(jié)果輸出?--></div> </body> </html>代碼中有相應(yīng)的注釋,就不贅述了。
這里有個(gè)核心就是前端要有代碼編輯區(qū)域,單純的div是無法滿足代碼編輯需求的,比如代碼高亮,簡(jiǎn)單的語法報(bào)錯(cuò)等,通過簡(jiǎn)單搜索,發(fā)現(xiàn)ace(https://github.com/ajaxorg/ace)這個(gè)項(xiàng)目,該項(xiàng)目通過JS實(shí)現(xiàn)了支持代碼高亮的代碼編輯器。
閱讀ace的文檔發(fā)現(xiàn)項(xiàng)目作者提供了打包好的版本ace-builds(https://github.com/ajaxorg/ace-builds/),我們可以直接使用。
通過git clone拉取ace-builds項(xiàng)目,然后將src中的所有代碼文件都賦值front-end/lib中,這些就是不同編程語言對(duì)應(yīng)著其中的文件。
獲取了ace后,我們還需要使用它,在ide.js中,我們寫入如下代碼:
let?editor;window.onload?=?function()?{//?載入aceeditor?=?ace.edit("editor");//?設(shè)置編輯器主題editor.setTheme("ace/theme/monokai");//?設(shè)置編輯器解析的編程語言editor.session.setMode("ace/mode/c_cpp");}//?選擇不同編程語言時(shí),需要切換ace的modefunction?changeLanguage()?{let?language?=?$("#languages").val();if?(language?==?'c'?||?language?==?'cpp')?{editor.session.setMode("ace/mode/c_cpp");}?else?if?(language?==?'python'){editor.session.setMode("ace/mode/python");}else?if?(language?==?'nodejs'){editor.session.setMode("ace/mode/javascript");};}//?用戶寫完代碼,點(diǎn)擊運(yùn)行時(shí),將代碼通過Ajax發(fā)送至Python后端function?runCode()?{$.ajax({url:?"/run_code",method:?"POST",data:?{language:?$("#languages").val(),code:?editor.getSession().getValue()},success:?function(response)?{console.log('success');console.log(response);$('.output').text(response);}})}至此,前端就開發(fā)完了。
后端開發(fā)
后端我選擇Flask來開發(fā),非常快,直接基于Flask docs里提供的代碼,復(fù)制粘貼,再修修改改則可,我們將代碼寫到back-end的serve.py中,代碼如下:
import?subprocess import?os import?time from?flask?import?Flask from?flask?import?render_template from?flask?import?requesttemplate_dir?=?os.path.abspath("../front-end") static_folder?=?os.path.abspath("../front-end") app?=?Flask(__name__,?static_folder=static_folder,?template_folder=template_dir)@app.route("/run_code",??methods=['GET',?'POST']) def?run_code():if?request.method?==?'POST':"""1.接收到前端信息2.將其存入文件中3.使用相關(guān)的解釋器去執(zhí)行文件中的代碼4.將執(zhí)行的結(jié)果返回給前端"""code?=?request.values.get('code')language?=?request.values.get('language')code_file_path?=?os.path.join(os.path.abspath('codes'))?+?str(time.time())?+?'.code'with?open(code_file_path,?'w')?as?f:f.write(code)if?language?==?'python':py_path?=?'c:\\users\\admin\\appdata\\local\\programs\\python\\python38\\python.exe'process?=?subprocess.Popen([py_path,?code_file_path],stdout=subprocess.PIPE,stderr=subprocess.PIPE)stdout,?stderr?=?process.communicate()output?=?stdout?+?stderrelif?language?==?'nodejs':node_path?=?r'C:\Program?Files\nodejs\node.exe'process?=?subprocess.Popen([node_path,?code_file_path],stdout=subprocess.PIPE,stderr=subprocess.PIPE)stdout,?stderr?=?process.communicate()output?=?stdout?+?stderrreturn?outputelif?request.method?==?'GET':return?render_template("ide.html",?name="run?code")if?__name__?==?"__main__":app.run(port=8001)上述代碼沒啥難度,就是設(shè)置了一個(gè)run_code接口,如果是GET請(qǐng)求,則返回HTML頁面(ide.html),如果是POST,則按編程語言的類型選擇相應(yīng)的解釋器,去執(zhí)行相應(yīng)的代碼。
通過Python的subprocess,利用shell的形式執(zhí)行代碼。
效果
運(yùn)行項(xiàng)目,先用Python來實(shí)現(xiàn)斐波那契數(shù)列,效果如下:
換成JavaScript來實(shí)現(xiàn)斐波那契數(shù)列,效果如下:
結(jié)尾
哦豁,實(shí)現(xiàn)下來,比我想象的簡(jiǎn)單,整個(gè)直播的過程對(duì)我來說有點(diǎn)像限時(shí)編程,播完后,有點(diǎn)累,但感覺開發(fā)出來挺爽的。
Enjoy Code,我們下篇文章見。
總結(jié)
- 上一篇: 03.获取网页源代码
- 下一篇: 多媒体_音乐播放器