调用Schoology API请求Token时触发fetch非法调用错误
调用Schoology API获取Request Token时出现"非法调用"错误的解决方案
问题场景
开发规划应用集成Schoology API时,使用第三方仓库调用getRequestToken()接口触发"非法调用"错误,错误定位在仓库代码的fetch调用处。
核心业务代码
import { SchoologyAPI } from 'schoology-api'; const client_key = "1234"; const secret = "000"; const client = new SchoologyAPI(client_key, secret, "https://schoology.[SchoolName].org/"); async function getClient () { client.getRequestToken() } export default function CreateHeader(){ getClient(); }
报错指向的仓库代码片段
async getRequestToken(): Promise<Token> { const Authorization = this.getUnsignedAuthHeader(); let res = await (await this.fetch(this.api_base + '/oauth/request_token', { headers: { Authorization } })).text(); const token = qsParse(res); this.setToken(token); return token; }
已尝试无效方案
- 改用
client.getRequestToken.call(),触发getUnsignedAuthHeader()无法读取的错误 - 参考同类"非法调用"问题的解决方案,均未解决
问题分析
- Node.js环境下fetch绑定缺失:仓库构造函数中,Node环境直接赋值
this.fetch = require("node-fetch"),但node-fetch作为函数调用时会丢失this上下文,导致非法调用错误。浏览器环境用了bind(window)处理,但Node环境未做绑定。 - 异步调用未等待:业务代码中调用
client.getRequestToken()未加await,虽不是直接报错原因,但会导致异步流程失控。
修复步骤
1. 修复仓库的fetch绑定逻辑
修改仓库构造函数的Node环境分支,确保fetch调用时上下文正确:
constructor(client_key: string, client_secret: string, site_base = DEFAULT_SITE_BASE, api_host: string = null) { if (IS_BROWSER) { this.fetch = window.fetch.bind(window) } else { const fetch = require("node-fetch"); // 绑定fetch自身作为上下文,避免调用时丢失this this.fetch = fetch.bind(fetch); } // 保留原有其他代码 this.client_key = client_key; this.client_secret = client_secret; this.site_base = site_base; this.api_base = `${(api_host ?? ((site_base.indexOf('schoologytest') !== -1) ? SCHOOLOGYTEST_API_HOST : SCHOOLOGY_API_HOST))}/v1`; this.redirectLoop = IS_BROWSER; }
2. 修正业务代码的异步调用
添加await并处理错误捕获:
import { SchoologyAPI } from 'schoology-api'; const client_key = "1234"; const secret = "000"; const client = new SchoologyAPI(client_key, secret, "https://schoology.[SchoolName].org/"); async function getClient () { try { const token = await client.getRequestToken(); console.log("获取Token成功:", token); // 后续业务逻辑 } catch (error) { console.error("获取Token失败:", error); // 错误处理逻辑 } } export default function CreateHeader(){ getClient(); }
3. 验证API基础路径(可选)
若学校域名特殊,可手动指定api_host确认路径正确性:
const client = new SchoologyAPI(client_key, secret, "https://schoology.[SchoolName].org/", "https://api.schoology.com");
内容的提问来源于stack exchange,提问作者ACCE
相关产品推荐
相关产品推荐

