如何使用Canvas LMS API配合UnityWebRequest等工具提交作业成绩
Unity侧实现(优先使用UnityWebRequest,兼容WebGL)
首先修正你现有代码的核心错误:鉴权头前缀错误,你当前填写的Basic是账户密码认证的前缀,Canvas Bearer Token要求使用Bearer前缀。
推荐直接用Unity官方原生的UnityWebRequest实现,避免第三方库兼容问题,示例代码如下:
using UnityEngine; using UnityEngine.Networking; using System.Collections; public class CanvasScoreSubmit : MonoBehaviour { // 测试用Token,后续切OAuth2后替换为动态获取的token private string apiToken = "你的Bearer Token"; // Canvas作业提交API地址,替换为你实际的接口地址 private string submitUrl = "你的Canvas API域名/api/v1/courses/课程ID/assignments/作业ID/submissions/用户ID"; public void SubmitScore(int finalScore) { StartCoroutine(SubmitRequest(finalScore)); } IEnumerator SubmitRequest(int score) { // 构造请求体,提交成绩用这个结构 string postData = JsonUtility.ToJson(new { submission = new { posted_grade = score.ToString() } }); // 如果要提交评论,用下面的请求体结构替换 // string postData = JsonUtility.ToJson(new { // submission = new { // comment = new { // text_comment = $"最终得分:{score}" // } // } // }); using (UnityWebRequest request = UnityWebRequest.Put(submitUrl, postData)) { request.method = UnityWebRequest.kHttpVerbPOST; request.SetRequestHeader("Content-Type", "application/json"); // 正确的Bearer鉴权头 request.SetRequestHeader("Authorization", $"Bearer {apiToken}"); yield return request.SendWebRequest(); if (request.result != UnityWebRequest.Result.Success) { Debug.LogError($"提交失败:{request.error},响应内容:{request.downloadHandler.text}"); } else { Debug.Log($"提交成功,响应内容:{request.downloadHandler.text}"); } } } }
注意:如果是WebGL构建,不要在客户端硬编码Bearer Token,避免泄露,建议走Node层做代理转发。
Node侧接口实现(无需第三方Canvas库)
你之前使用的第三方封装库兼容问题较多,可以直接用原生HTTP请求或者轻量axios实现,完全适配你的需求,示例代码如下:
const express = require('express'); const axios = require('axios'); const app = express(); app.use(express.json()); // Canvas配置 const CANVAS_API_TOKEN = '你的Canvas Bearer Token'; const CANVAS_DOMAIN = '你的Canvas域名'; // 给Unity调用的提交接口 app.post('/submit-score', async (req, res) => { const { courseId, assignmentId, userId, score, comment } = req.body; try { const response = await axios({ method: 'POST', url: `${CANVAS_DOMAIN}/api/v1/courses/${courseId}/assignments/${assignmentId}/submissions/${userId}`, headers: { 'Authorization': `Bearer ${CANVAS_API_TOKEN}`, 'Content-Type': 'application/json' }, data: { submission: comment ? { comment: { text_comment: comment } } : { posted_grade: score.toString() } } }); res.status(200).json(response.data); } catch (err) { res.status(err.response?.status || 500).json({ error: err.message, detail: err.response?.data }); } }); app.listen(3000, () => { console.log('服务运行在端口3000'); });
Unity侧直接请求你部署的Node服务/submit-score接口即可,避免跨域问题,同时Token保存在服务端不会泄露。
注意事项
- 确保你的Bearer Token有对应课程作业的评分权限,Postman能请求成功说明权限没有问题,直接把Postman里的Header配置对应到代码即可
- 后续切换OAuth2只需要修改Node侧或者Unity侧的Token获取逻辑,提交请求的代码不需要改动
- WebGL构建前需要在Node服务配置CORS允许Unity域名访问,避免跨域拦截
内容的提问来源于stack exchange,提问作者user16346610
相关产品推荐
相关产品推荐

