概览
本系统提供 6 个 RESTful API 接口,基于 Cloudflare Workers 运行时和 KV 存储构建 及CST-KV快捷存储。所有接口统一使用 POST 方法,请求和响应均为 JSON 格式。
| 方法 | 路径 | 说明 | 鉴权 |
|---|---|---|---|
| POST | /v1 |
提交学生数据 | 无需 |
| POST | /v1/all |
获取全部数据 | 需要 |
| POST | /v1/stats |
统计信息 | 需要 |
| POST | /v1/export |
导出CSV文件 | 需要 |
| POST | /v1/delete |
批量删除记录 | 需要 |
| POST | /v1/delete-one |
删除单条记录 | 需要 |
鉴权说明
管理接口(查询、统计、导出、删除)需要在请求 Body 中传入 password 字段进行鉴权。密码错误将返回 403。
// 所有管理接口都需要在 Body 中携带 password
{
"password": "your_admin_password",
// ... 其他参数
}
安全提示
默认密码硬编码在 Worker 代码的 CONFIG.ADMIN_PASSWORD 中,生产环境请务必修改。
接口详情
/v1
·
提交学生数据
学生提交项目答案和分数。此接口无需鉴权,但受 IP 频率限制。
请求参数 (Body · JSON)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | string | 是 | 1-4个中文汉字 |
class | string | 是 | 班级名称,不能为空 |
score | number | 是 | 0-100 整数 |
answer1 | string | 否 | 答案1 |
answer2 | string | 否 | 答案2 |
answer3 | string | 否 | 答案3 |
answer4 | string | 否 | 答案4 |
answer5 | string | 否 | 答案5 |
请求示例
curl -X POST https://your-worker.workers.dev/v1 \
-H "Content-Type: application/json" \
-d '{
"name": "张三",
"class": "计科2301",
"score": 95,
"answer1": "项目说明内容",
"answer2": "技术实现方案",
"answer3": "测试结果",
"answer4": "",
"answer5": ""
}'
响应示例
/v1/all
·
获取全部数据
需要密码
获取所有提交记录,按提交时间倒序排列。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
password | string | 是 | 管理密码 |
请求示例
curl -X POST https://cstapi.cc.cd/v1/all \
-H "Content-Type: application/json" \
-d '{ "password": "your_password" }'
响应示例
{
"code": 200,
"data": [
{
"id": "sub_1718000000000_abc123def",
"name": "萃文学生",
"class": "700",
"score": 100,
"answers": {
"answer1": "这是第1题答案",
"answer2": "这是第2题答案",
"answer3": "这是第3题答案",
"answer4": "这是第4题答案",
"answer5": "这是第5题答案"
},
"ip": "8.8.8.8",
"time": "2025/6/10 14:30:00",
"timestamp": 1718000000000
}
]
}
/v1/stats
·
统计信息
需要密码
返回提交数据的统计摘要,包含总分、平均分、最高分、及格率及分数分布。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
password | string | 是 | 管理密码 |
响应示例
{
"code": 200,
"stats": {
"total": 42,
"avg": "78.5",
"max": 100,
"passRate": "85.7",
"distribution": {
"0-19": 2,
"20-39": 1,
"40-59": 3,
"60-79": 12,
"80-99": 18,
"100": 6
}
}
}
/v1/export
·
导出CSV
需要密码
导出所有数据为 CSV 文件(UTF-8 BOM 编码),直接返回文件流而非 JSON。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
password | string | 是 | 管理密码 |
前端下载示例
const res = await fetch('/v1/export', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ password: 'your_password' })
});
// 返回的是 CSV 文件流,不是 JSON
const blob = await res.blob();
const url = URL.createObjectURL(blob);
// 触发下载
const a = document.createElement('a');
a.href = url;
a.download = 'data.csv';
document.body.appendChild(a);
a.click();
URL.revokeObjectURL(url);
a.remove();
注意
此接口返回 text/csv 而非 JSON。CSV 包含 BOM 标记(\uFEFF),可直接用 Excel 打开而不会乱码。
/v1/delete
·
批量删除
需要密码
危险操作
根据 ID 数组批量删除记录,同时更新索引。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
password | string | 是 | 管理密码 |
ids | string[] | 是 | 要删除的记录 ID 数组 |
请求 / 响应示例
// 请求
{
"password": "your_password",
"ids": [
"sub_1718000000000_abc123",
"sub_1718000000001_def456"
]
}
// 响应
{
"code": 200,
"msg": "删除成功",
"deleted": 2
}
/v1/delete-one
·
单条删除
需要密码
根据 ID 删除单条记录。ID 必须以 sub_ 开头。
请求参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
password | string | 是 | 管理密码 |
id | string | 是 | 记录 ID,须以 sub_ 开头 |
响应示例
// 成功
{ "code": 200, "msg": "删除成功" }
// ID 无效
{ "code": 400, "msg": "无效ID" }
错误码一览
| HTTP 状态码 | code | 含义 | 典型场景 |
|---|---|---|---|
200 | 200 | 成功 | 请求正常处理 |
400 | 400 | 参数错误 | 姓名格式不对、分数超范围、缺少必填项 |
403 | 403 | 鉴权失败 | 密码错误 |
404 | 404 | 接口不存在 | 路径写错 |
429 | 429 | 频率限制 | 同一 IP 提交次数达上限 |
500 | 500 | 服务器异常 | KV 未绑定、代码执行异常 |
频率限制
提交接口(POST /v1)基于 IP 进行频率限制,同一 IP 在每个时间桶内最多提交 100 次。
时间桶规则
- •08:00-20:00 → 按小时分桶
- •20:00-08:00 → 合并至次日 08:00 桶
限制参数
- •每桶上限:100 次/IP
- •桶过期 TTL:86400 秒
完整调用示例
以下是一个完整的 HTML 页面示例,演示如何调用提交接口并与后端交互。
<!-- 学生项目提交 - 前端调用示例 -->
<form id="submitForm">
<input type="text" id="name" placeholder="姓名" required/>
<input type="text" id="cls" placeholder="班级" required/>
<input type="number" id="score" placeholder="分数" required/>
<textarea id="a1" placeholder="答案1"></textarea>
<button type="submit">提交</button>
</form>
<script>
const API_BASE = 'https://your-worker.workers.dev';
document.getElementById('submitForm')
.addEventListener('submit', async (e) => {
e.preventDefault();
// 构造请求体
const payload = {
name: name.value.trim(),
class: cls.value.trim(),
score: parseInt(score.value),
answer1: a1.value
};
// 调用提交接口
try {
const res = await fetch(API_BASE + '/v1', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
const data = await res.json();
if (data.code === 200) {
alert('提交成功!剩余 ' + data.remaining + ' 次');
} else {
alert('错误: ' + data.msg);
}
} catch (err) {
alert('网络错误: ' + err.message);
}
});
</script>
内置前端页面
Worker 内置了两个前端页面,直接通过浏览器访问即可使用,无需额外部署。
部署说明
1. 创建 KV 命名空间
wrangler kv:namespace create "SUBMISSIONS"
2. 配置 wrangler.toml
name = "student-submit"
main = "worker.js"
compatibility_date = "2026-01-01"
[[kv_namespaces]]
binding = "SUBMISSIONS"
id = "你的KV命名空间ID"
3. 部署
wrangler deploy