You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Office 365 OWA更新后getCallbackTokenAsync返回失败,客户端正常

解决OWA新UI下getCallbackTokenAsync()传递类对象作为asyncContext失败的问题

这个问题的核心原因是Office.js在OWA新UI的更新后,对asyncContext的序列化机制做了调整——旧版本可能支持传递类实例,但新UI下只允许传递可被JSON序列化的简单类型(比如字符串、无原型的普通对象),类对象因为包含原型链、不可枚举属性或函数引用,无法被正确序列化,最终导致请求失败。

下面给你几种可靠的解决方案,帮你正确传递上下文并获取令牌完成认证:

方案1:用唯一标识符映射类实例

如果必须关联类对象的上下文,可以给每个类实例分配唯一ID,把ID作为asyncContext传递,在回调里通过ID找到对应的类实例:

class MailProcessor {
  constructor() {
    // 生成唯一实例ID
    this.instanceId = `mail-proc-${Date.now()}-${Math.random().toString(36).slice(2)}`;
    // 把实例存入全局映射表
    MailProcessor.instances[this.instanceId] = this;
  }

  fetchTokenAndProcess() {
    Office.context.mailbox.getCallbackTokenAsync({ isRest: true }, (asyncResult) => {
      if (asyncResult.status === Office.AsyncResultStatus.Succeeded) {
        // 通过asyncContext里的ID获取类实例
        const processor = MailProcessor.instances[asyncResult.asyncContext];
        processor.processWithToken(asyncResult.value);
        // 使用后清理映射,避免内存泄漏
        delete MailProcessor.instances[asyncResult.asyncContext];
      } else {
        console.error("获取令牌失败:", asyncResult.error);
      }
    }, this.instanceId); // 传递实例ID作为asyncContext
  }

  processWithToken(token) {
    // 这里编写用令牌访问ExtendedProperty的认证逻辑
    console.log("获取到令牌:", token);
    // 示例:调用REST API获取扩展属性
    const itemId = Office.context.mailbox.item.itemId;
    const restUrl = `${Office.context.mailbox.restUrl}/v2.0/me/messages/${itemId}/singleValueExtendedProperties`;
    fetch(restUrl, {
      headers: { Authorization: `Bearer ${token}` }
    })
    .then(res => res.json())
    .then(data => console.log("ExtendedProperty数据:", data))
    .catch(err => console.error("访问扩展属性失败:", err));
  }
}

// 静态属性存储实例映射
MailProcessor.instances = {};

方案2:利用闭包捕获类实例(更简洁)

不需要依赖asyncContext,直接在回调里通过闭包访问当前类实例:

class MailProcessor {
  fetchTokenAndProcess() {
    const self = this; // 捕获当前类实例
    Office.context.mailbox.getCallbackTokenAsync({ isRest: true }, (asyncResult) => {
      if (asyncResult.status === Office.AsyncResultStatus.Succeeded) {
        self.processWithToken(asyncResult.value);
      } else {
        console.error("获取令牌失败:", asyncResult.error);
      }
    });
    // 此处无需传递asyncContext
  }

  processWithToken(token) {
    // 令牌使用逻辑...
    console.log("令牌已获取,开始处理邮件扩展属性");
    // 你的认证和业务代码写在这里
  }
}

额外注意事项

  • 确保使用最新稳定版的Office.js,微软可能会修复这类兼容性问题,但优先用上面的兼容写法更稳妥。
  • 测试时清理浏览器缓存,确保OWA加载的是最新的插件代码和Office.js库。
  • 如果需要传递更多上下文数据,可以用普通对象(无原型、无函数)作为asyncContext,比如:asyncContext: { userId: 123, taskId: 'abc' },这类对象能被正确序列化。

内容的提问来源于stack exchange,提问作者Ajit Hogade

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:27:21