You need to enable JavaScript to run this app. 如何使用Canvas LMS API配合UnityWebRequest等工具提交作业成绩
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 17:15:04