从零部署一个在线 C 编辑器:Gitee、Judge0 和 EdgeOne Makers
我之前的在线 C 编辑器跑在 EdgeOne Pages 上,但一直有几个问题:函数写法不兼容、中文输入法会引入非法字符、部署后前端缓存导致新旧版本冲突。
这次把它重做了一遍,改名叫番星C语言编辑器,迁移到了 EdgeOne Makers。整体思路没变:打开网页,写 C 代码,点一下运行,就能看到编译和运行结果。不需要本地装 GCC,也不需要配置 IDE。
这篇文章记录实现过程、迁移细节,以及从 Gitee 部署到 EdgeOne Makers 的完整步骤。
线上地址:
1 | https://c.xingbox.me |
先看成品
页面主要分成三块:
- 左侧是 C 代码编辑器
- 右上是运行输出
- 右下是标准输入 stdin
默认代码是:
1 |
|
点击「编译运行」之后,前端把代码提交到 /api 边缘函数,边缘函数调用 Judge0 编译运行后返回 stdout、stderr、compile_output、运行时间和内存占用。
如果代码有语法错误,就展示编译错误;如果运行成功,就展示程序输出。
页面底部有一行部署状态检测,可以直接看到当前版本和 /api 是否正常:
1 | JS: v2026.07.09-edgeone | edgeApiUrl: /api | /api: 正常 |
如果 /api 还没生效(比如浏览器还在用旧版 JS),会显示:
1 | edgeApiUrl: 未配置 | /api: 旧版JS,需强刷 |
这个检测在排查部署问题时很实用。
技术选型
| 部分 | 方案 |
|---|---|
| 页面 | 原生 HTML/CSS/JS |
| 编辑器 | CodeMirror 5 |
| 编译运行 | Judge0 CE |
| API 函数 | EdgeOne Makers Edge Functions |
| 代理函数 | EdgeOne Makers Edge Functions(备用) |
| 部署 | Gitee + EdgeOne Makers |
没有用 Vue、React,也没有引入复杂构建流程。原因很直接:这个工具的交互不复杂,核心问题不是组件状态管理,而是如何稳定地把代码送到远端编译服务并拿回结果。
整体原理
迁移到 EdgeOne Makers 之后,链路变成了这样:
1 | 用户浏览器 |
和之前 EdgeOne Pages 的方案相比,主要区别是:
- 之前前端自己 base64 编码,通过
/proxy?url=...透传给 Judge0 - 现在前端发送明文代码,
/api边缘函数负责编码、调用、解码,前端拿到的是直接可用的 JSON
这样做的好处是前端逻辑更简单,编码解码全部在边缘节点完成,减少了前端出错的可能。
为什么从 EdgeOne Pages 迁移到 EdgeOne Makers
之前用的是 EdgeOne Pages Functions,函数格式是 Cloudflare Workers 风格:
1 | export default { |
EdgeOne Makers 要求的格式是:
1 | export default async function onRequest(context) { |
迁移到 EdgeOne Makers 之后,函数格式统一了,也更容易和 Cloud Functions、Agents 等其他模块配合。
前端配置
页面里放了一个全局配置:
1 | window.__APP_CONFIG__ = { |
各字段含义:
edgeApiUrl:EdgeOne Makers 的/api地址(主路径)judge0ProxyUrl:旧的/proxy代理地址(备用路径)judge0ApiUrl:真实的 Judge0 地址backendRunUrl:备用 Node 后端地址,目前留空
前端的提交逻辑是:先尝试 /api,如果失败再回退到 /proxy,最后回退到直连 Judge0。这样即使某个环节出问题,编译功能也不会完全挂掉。
/api 边缘函数
这是这次迁移的核心改动。文件在 edge-functions/api/index.js,自动映射为 /api 路由。
1 | const JUDGE0_URL = 'https://ce.judge0.com'; |
几个注意点:
- 入参兼容:
context可能是请求对象本身,也可能是包含request属性的上下文对象,所以做了context instanceof Request判断。 - GET 健康检查:访问
GET /api会返回{"ok":true},前端的部署状态检测就是用这个接口。 - base64 编码解码全在边缘节点完成:前端发的是明文代码,拿到的是明文结果。
/proxy 代理函数(备用)
edge-functions/proxy.js 仍然保留了旧的 ?url= 代理方式,作为 /api 失败时的回退路径。
它和之前逻辑一样:读 ?url= 参数,验证域名白名单,转发到 Judge0。只是格式也从 fetch(request, env) 改成了 onRequest(context)。
迁移中踩的坑
1. 函数格式不兼容
EdgeOne Pages Functions 用 { fetch(request, env) } 写法,EdgeOne Makers 用 onRequest(context) 写法。直接推旧代码上去,函数不会报错但也不会执行。
2. \n 被当成真实换行符
默认模板原来用的是:
1 | printf("Hello, World!\n"); |
但在某些环境下,JavaScript 模板字符串里的 \n(反斜杠+n,两个字符)会被处理成真实换行符,导致 C 编译器看到字符串跨行,报 missing terminating " character。
最后的解决办法有两个:
- 默认模板改用
puts("Hello, World!"),从根源避开反斜杠 STORAGE_VERSION从 2 升到 3,强制清除所有旧 localStorage 缓存
3. /api 部署了但前端没调用
部署后 /api 边缘函数已经注册成功,但浏览器还在加载旧版 JS,没有 edgeApiUrl 配置。需要强刷页面(Ctrl+Shift+R)才能加载新版 JS。
这就是为什么加了部署状态检测——一眼就能看出浏览器跑的是新版还是旧版。
4. 中文输入法导致编译失败
用户在中文输入法下打出的弯引号 ""、全角标点 ,;: 等,在 C 代码里是非法字符。前端加了 sanitizeCode() 函数,提交前自动替换:
- 弯引号
""''→ 移除 - 全角双引号
"→ 英文引号" - 全角逗号
,→ 英文逗号, - 全角分号
;→ 英文分号; - 以及其他十几种常见的中文标点
部署步骤
第一步:把项目推到 Gitee
仓库地址:
1 | git@gitee.com:knight3fax/c-online-compiler.git |
确认仓库里至少有这些文件:
1 | index.html |
第二步:在 EdgeOne Makers 创建项目
在 EdgeOne Makers 控制台新建项目,关联 Gitee 仓库:
1 | knight3fax/c-online-compiler |
构建配置:
1 | 框架预设:Other / Static |
项目没有打包步骤,根目录本身就是静态站点的输出目录。
第三步:确认 Edge Functions 生效
部署完成后,访问:
1 | https://c.xingbox.me/api |
如果返回 {"ok":true,...},说明 /api 函数已经生效。
也可以访问:
1 | https://c.xingbox.me/proxy |
如果返回 Missing url parameter,说明 /proxy 函数也正常。
EdgeOne Makers 控制台的 edgeFunctionsRoutes 应该能看到:
1 | [ |
第四步:绑定域名
在 EdgeOne Makers 项目设置里绑定自定义域名 c.xingbox.me,按提示配置 DNS CNAME 记录,等证书签发和 DNS 生效后即可访问。
第五步:验证编译功能
打开页面,点「编译运行」,底部应该显示:
1 | [输出] |
如果显示的是”后端: Judge0 CE (官方)”,说明 /api 没走通,走了 proxy 回退,检查页脚的部署状态检测信息。
常见问题排查
页面能打开,但点击运行失败
先访问 https://c.xingbox.me/api 看是否返回 {"ok":true}。
如果 /api 正常,打开浏览器开发者工具看 Network 面板的请求状态码。
页脚显示”旧版JS,需强刷”
浏览器缓存了旧版 JS 文件。按 Ctrl+Shift+R(或 Cmd+Shift+R)强刷页面即可。
/api 返回 500
打开浏览器开发者工具,看 /api 响应的 JSON 里有没有 error 和 stack 字段,通常会说明具体哪一步出了问题。
返回 429
这是 Judge0 公共服务限流。等一会儿再试,或者自己部署 Judge0 实例。
目前的限制
- 只支持 C 语言(GCC 12.2.0)
- 使用 Judge0 CE 公共服务,可能会被限流
- 运行时间限制 5 秒,代码长度限制 32KB
- 依赖 cdnjs 加载 CodeMirror,网络差时可能加载慢
后续可以考虑:
- 增加 C++、Python、Java 等语言
- 把 CodeMirror 资源本地化
- 接入自建 Judge0 实例减少限流
总结
这个编辑器本质上是”静态前端 + 边缘函数 + 第三方编译 API”的组合。迁移到 EdgeOne Makers 之后,函数格式更规范,API 链路也更简洁——前端不再需要自己做 base64 编码,边缘函数全部搞定。
对我而言,这个项目最有价值的地方不是技术多高级,而是链路足够完整:从写代码到看到运行结果,一个页面闭环。教学场景下用起来很顺手。
- GitHub:https://github.com/xxx/xxx
- 文档:https://xxx
- 线上:https://xxx
本文为 AI 辅助编写,重写版本
- 标题: 从零部署一个在线 C 编辑器:Gitee、Judge0 和 EdgeOne Makers
- 作者: 番星
- 创建于 : 2026-07-09 22:00:00
- 更新于 : 2026-07-09 22:00:00
- 链接: https://xingbox.me/fanxing-online-c-edgeone-judge0/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。