如何从TypeScript重新加载Outlook加载项?授权后重载问题
Outlook加载项授权后重新加载解决方案
问题核心
你遇到的问题在于:Outlook加载项运行在Office沙箱环境中,普通DOM刷新方法(如window.location.reload())无法正确触发加载项重新加载,必须使用Office官方API处理。同时,window.open打开授权页无法感知用户完成授权的时机,导致加载项持续卡顿。
解决步骤
1. 用Office Dialog API替代window.open
Office提供的displayDialogAsync可打开授权页,并在对话框关闭时触发回调,能可靠感知授权完成时机,还能避免跨域问题:
async getUser(token: any, needsExchange: boolean) { try { const res = await axios.post<any, AxiosResponse<any>>( (process.env.APP_NAME === "outlook_local" ? process.env.BASE_URL_WSC : window.location.origin ?? process.env.BASE_URL) + "api", { AccessToken: token, Application: process.env.APP_NAME, NeedsExchange: needsExchange } ); return res.data; } catch (err) { const errorCode = err.response?.data?.errors?.[0]?.errorCode; if (errorCode === 65001 || err.response?.data?.er) { // 调用Office Dialog打开授权页 Office.context.ui.displayDialogAsync(process.env.CONSENT_URL, { height: 50, width: 50 }, (asyncResult) => { const dialog = asyncResult.value; // 监听对话框关闭事件 dialog.addEventHandler(Office.EventType.DialogEventReceived, async (args) => { if (args.error === 0) { // 对话框正常关闭,判定授权完成 // 使用Office官方API重新加载加载项 await Office.addin.reload(); } }); }); } const errorInfo = err.response?.data?.info ?? t("notifications.serverError"); console.log(errorInfo); NotificationManager.error(errorInfo, t("notifications.error"), 60000); throw err; // 抛出错误避免后续逻辑异常 } }
2. 强制使用Office加载项刷新API(兼容window.open场景)
如果必须用window.open,可通过定时轮询检查授权状态,确认完成后调用Office.addin.reload():
async getUser(token: any, needsExchange: boolean) { try { const res = await axios.post<any, AxiosResponse<any>>( (process.env.APP_NAME === "outlook_local" ? process.env.BASE_URL_WSC : window.location.origin ?? process.env.BASE_URL) + "api", { AccessToken: token, Application: process.env.APP_NAME, NeedsExchange: needsExchange } ); return res.data; } catch (err) { const errorCode = err.response?.data?.errors?.[0]?.errorCode; if (errorCode === 65001 || err.response?.data?.er) { window.open(process.env.CONSENT_URL, '_blank'); // 启动定时轮询,检查授权状态 const checkAuthInterval = setInterval(async () => { try { // 调用轻量化接口验证授权是否成功 await axios.get('/api/check-auth'); // 替换为你的授权验证接口 // 授权成功,停止轮询并刷新加载项 clearInterval(checkAuthInterval); await Office.addin.reload(); } catch (checkErr) { // 授权未完成,继续轮询 } }, 3000); // 每3秒检查一次 } const errorInfo = err.response?.data?.info ?? t("notifications.serverError"); console.log(errorInfo); NotificationManager.error(errorInfo, t("notifications.error"), 60000); throw err; } }
3. 关键注意事项
- 必须使用
Office.addin.reload()而非普通DOM刷新方法,这是Office官方针对加载项的刷新API,能正确触发沙箱环境内的加载项重启。 - 使用
displayDialogAsync时,需将授权页域名添加到加载项清单的AppDomains列表中,否则会触发跨域错误。 - 轮询方案中的验证接口需尽量轻量化,避免对服务器造成不必要的压力。
内容的提问来源于stack exchange,提问作者MatejDodevski
相关产品推荐
相关产品推荐

