Office 365 outlook 约会加载项无法启动
Office 365 outlook appointment addin does not start
我们在尝试加载 Outlook 约会插件时遇到问题。我们的命令显示在功能区 ui 中,插件正在尝试启动,我们可以跟踪对我们的 wev-app 的调用。我们在跟踪中没有收到任何错误,404 或 500,并且服务响应我们的第一个 html-页面,其中包含一个文本和一个按钮来启动我们的身份验证。
但是在返回 html 之后,outlook 只是停止了插件的微调器并且没有显示任何内容。有什么好的方法可以调试它以了解正在发生的事情吗?
html-页面非常简单,仅包含以下代码。
<head>
<title>Office-bokning</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://appsforoffice.microsoft.com/fabric/2.2.0/fabric.min.css">
<link rel="stylesheet" href="https://appsforoffice.microsoft.com/fabric/2.2.0/fabric.components.min.css">
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/Office.js" type="text/javascript"></script>
<!--[authentication-popup-script]-->
<script>
startCheck = function () {
var checkCode = setInterval(function () {
localStorage.setItem('dummy', "dummy");
localStorage.removeItem('dummy');
var code = localStorage.getItem('code');
var externalProviderUserId = localStorage.getItem('externalProviderUserId');
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
var fallbackCode;
var fallbackExternalProviderUserId;
if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {
fallbackCode = readCookie('NAME_OF_COOKIE');
fallbackExternalProviderUserId = readCookie('externalProviderUserId');
}
console.log("code " + code);
if (code || fallbackCode) {
clearInterval(checkCode);
var http = new XMLHttpRequest();
var url = [URL]
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "text/plain");
//var that = this;
http.onreadystatechange = function () {
if (http.readyState == 4 && http.status == 200) {
localStorage.removeItem('code');
localStorage.removeItem('externalProviderUserId');
window.location.href = "[URL]";
//location.reload();
}
}
http.send(params);
}
}, 1000);
}
startCheck();
</script>
</head>
<body class="container-fluid" style="padding-left: 0px; padding-right: 0px; height: 100%">
<p>
Some text describing the addin...
</p>
<!--[popup-button]-->
<script>
Office.initialize = function (reason) {
console.log("authorize office init" + reason);
var butan = document.getElementById('loginButton');
if (butan)
butan.style.display = 'block';
}
function commandFunction(event) {
event.completed();
}
</script>
</body>
您粘贴的 HTML 没有对 Office.js 的引用:<script src="https://appsforoffice.microsoft.com/lib/1/hosted/Office.js" type="text/javascript"></script>
TL;DR : 看来您想弹出一个页面进行身份验证。使用 displayDialogAsync API 来做到这一点。
查看您的代码,我没有发现任何问题。此外,根据您的代码,您描述的行为实际上是正确的。
我看到您有一个名为 "commandFunction" 的函数,它接受一个 "event" 参数。我的猜测是您的清单中有一个调用 commandFunction 的 ExecuteFunction。
因此,当用户在约会 window 的功能区 ui 中单击您的加载项按钮时,Outlook 将加载您的 html 网页,调用 "Office.initialize" ,在约会 window 的 "Subject" 字段上方显示您的应用程序的默认微调器,然后调用 "commandFunction"。此函数中的唯一代码是 "event.completed",因此 Outlook 会调用该代码,这基本上会结束您的应用程序的执行,此时 Outlook 会删除默认的微调器以发出完成信号。这正是您正在经历的。
在调用 "event.completed" 之前,您必须 运行 "commandFunction" 中的任何相关代码。因此,例如,您可以添加代码,在调用 "event.completed" 之前向约会添加通知 message/infobar。示例代码如下:
function commandFunction(event)
{
Office.context.mailbox.item.notificationMessages.addAsync
(
"some_unique_id_such_as_a_guid",
{
type: Office.MailboxEnums.ItemNotificationMessageType.InformationalMessage,
persistent: false,
message: "hello world",
icon: "default_icon"
},
function (asyncResult)
{
// check asyncResult.status
// do something
event.completed(true);
}
);
}
您似乎想打开一个 html window 供用户在继续执行您的应用程序之前进行身份验证。在这种情况下,您应该通过在 "event.completed" 之前在 "commandFunction" 中调用它来使用 "displayDialogAsync" API。这将打开一个指向身份验证页面 URL 的 IE window。示例代码如下:
function commandFunction(event)
{
Office.context.ui.displayDialogAsync
(
"https://ur/to/auth/page",
{
width: 50,
height: 45,
requireHTTPS: true
},
function (asyncResult)
{
// check asyncResult.status
// do something
event.completed(true);
}
);
}
displayDialogAsync API 的文档位于:https://github.com/OfficeDev/office-js-docs/blob/master/reference/shared/officeui.md
为了调试,打开 IE,转到 'Internet Options' -> 'General tab' -> 单击 'Settings' 按钮打开 'Website Data Settings' window。在 'Temporary Internet Files' 选项卡中,在 'Check for newer versions of stored pages'、select 'Every time I visit the webpage' 下。单击确定。
现在转到 'Advanced' 选项卡 -> 'Settings' 部分并取消选中以下内容:
- 禁用脚本调试 (Internet Explorer)
- 禁用脚本调试(其他)
然后检查以下内容:
- 显示有关每个脚本错误的通知
然后在"commandFunction"的第一行添加"debugger;":
function commandFunction(event)
{
debugger;
// add other code below...
}
这将提示您在 运行 应用程序时调试代码。如果您有任何其他问题,您可以在 Visual Studio 中调试并检查您的代码。
我们在尝试加载 Outlook 约会插件时遇到问题。我们的命令显示在功能区 ui 中,插件正在尝试启动,我们可以跟踪对我们的 wev-app 的调用。我们在跟踪中没有收到任何错误,404 或 500,并且服务响应我们的第一个 html-页面,其中包含一个文本和一个按钮来启动我们的身份验证。
但是在返回 html 之后,outlook 只是停止了插件的微调器并且没有显示任何内容。有什么好的方法可以调试它以了解正在发生的事情吗?
html-页面非常简单,仅包含以下代码。
<head>
<title>Office-bokning</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://appsforoffice.microsoft.com/fabric/2.2.0/fabric.min.css">
<link rel="stylesheet" href="https://appsforoffice.microsoft.com/fabric/2.2.0/fabric.components.min.css">
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/Office.js" type="text/javascript"></script>
<!--[authentication-popup-script]-->
<script>
startCheck = function () {
var checkCode = setInterval(function () {
localStorage.setItem('dummy', "dummy");
localStorage.removeItem('dummy');
var code = localStorage.getItem('code');
var externalProviderUserId = localStorage.getItem('externalProviderUserId');
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
var fallbackCode;
var fallbackExternalProviderUserId;
if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {
fallbackCode = readCookie('NAME_OF_COOKIE');
fallbackExternalProviderUserId = readCookie('externalProviderUserId');
}
console.log("code " + code);
if (code || fallbackCode) {
clearInterval(checkCode);
var http = new XMLHttpRequest();
var url = [URL]
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "text/plain");
//var that = this;
http.onreadystatechange = function () {
if (http.readyState == 4 && http.status == 200) {
localStorage.removeItem('code');
localStorage.removeItem('externalProviderUserId');
window.location.href = "[URL]";
//location.reload();
}
}
http.send(params);
}
}, 1000);
}
startCheck();
</script>
</head>
<body class="container-fluid" style="padding-left: 0px; padding-right: 0px; height: 100%">
<p>
Some text describing the addin...
</p>
<!--[popup-button]-->
<script>
Office.initialize = function (reason) {
console.log("authorize office init" + reason);
var butan = document.getElementById('loginButton');
if (butan)
butan.style.display = 'block';
}
function commandFunction(event) {
event.completed();
}
</script>
</body>
您粘贴的 HTML 没有对 Office.js 的引用:<script src="https://appsforoffice.microsoft.com/lib/1/hosted/Office.js" type="text/javascript"></script>
TL;DR : 看来您想弹出一个页面进行身份验证。使用 displayDialogAsync API 来做到这一点。
查看您的代码,我没有发现任何问题。此外,根据您的代码,您描述的行为实际上是正确的。
我看到您有一个名为 "commandFunction" 的函数,它接受一个 "event" 参数。我的猜测是您的清单中有一个调用 commandFunction 的 ExecuteFunction。
因此,当用户在约会 window 的功能区 ui 中单击您的加载项按钮时,Outlook 将加载您的 html 网页,调用 "Office.initialize" ,在约会 window 的 "Subject" 字段上方显示您的应用程序的默认微调器,然后调用 "commandFunction"。此函数中的唯一代码是 "event.completed",因此 Outlook 会调用该代码,这基本上会结束您的应用程序的执行,此时 Outlook 会删除默认的微调器以发出完成信号。这正是您正在经历的。
在调用 "event.completed" 之前,您必须 运行 "commandFunction" 中的任何相关代码。因此,例如,您可以添加代码,在调用 "event.completed" 之前向约会添加通知 message/infobar。示例代码如下:
function commandFunction(event)
{
Office.context.mailbox.item.notificationMessages.addAsync
(
"some_unique_id_such_as_a_guid",
{
type: Office.MailboxEnums.ItemNotificationMessageType.InformationalMessage,
persistent: false,
message: "hello world",
icon: "default_icon"
},
function (asyncResult)
{
// check asyncResult.status
// do something
event.completed(true);
}
);
}
您似乎想打开一个 html window 供用户在继续执行您的应用程序之前进行身份验证。在这种情况下,您应该通过在 "event.completed" 之前在 "commandFunction" 中调用它来使用 "displayDialogAsync" API。这将打开一个指向身份验证页面 URL 的 IE window。示例代码如下:
function commandFunction(event)
{
Office.context.ui.displayDialogAsync
(
"https://ur/to/auth/page",
{
width: 50,
height: 45,
requireHTTPS: true
},
function (asyncResult)
{
// check asyncResult.status
// do something
event.completed(true);
}
);
}
displayDialogAsync API 的文档位于:https://github.com/OfficeDev/office-js-docs/blob/master/reference/shared/officeui.md
为了调试,打开 IE,转到 'Internet Options' -> 'General tab' -> 单击 'Settings' 按钮打开 'Website Data Settings' window。在 'Temporary Internet Files' 选项卡中,在 'Check for newer versions of stored pages'、select 'Every time I visit the webpage' 下。单击确定。
现在转到 'Advanced' 选项卡 -> 'Settings' 部分并取消选中以下内容:
- 禁用脚本调试 (Internet Explorer)
- 禁用脚本调试(其他)
然后检查以下内容:
- 显示有关每个脚本错误的通知
然后在"commandFunction"的第一行添加"debugger;":
function commandFunction(event)
{
debugger;
// add other code below...
}
这将提示您在 运行 应用程序时调试代码。如果您有任何其他问题,您可以在 Visual Studio 中调试并检查您的代码。