TL; DR
我使用sessionStorage在外接程序的不同部分之间进行通信,在撰写窗口中按下功能区按钮时执行的代码以及打开的对话框。这在浏览器中有效,但在桌面Outlook会话中,对话框中的Storage为空。有什么作用?
// TL; DR
我构建了一个js插件,该插件在网络浏览器中可以正常工作,但在台式机上却严重损坏。我宁愿在桌面上完全禁用它,因为还有一个VSTO插件,它的功能远远超过js api所能提供的,但是由于我还没有找到这样做的方法,所以我现在唯一的选择似乎是: js版本可在全球使用。
我发现桌面上正在运行所有“浏览器”的IE,并且已经在Outlook.com上使用IE调试了插件,但是我已经用尽了语法错误,现在遇到了问题只能在桌面外观上显示。
基本思想是:当用户启动此操作时,除非存在该对象,否则我想在sessionStorage中创建一个对象。然后,该对话框将读取对象,并向用户显示一个表单,提交该对象后,将更新该对象,应用设置并关闭该对话框。 出于某种原因,在桌面Outlook上,当对话框启动时,该键的sessionStorage为null,而在浏览器中(即使使用IE)也已正确初始化。
我尝试使用F12Chooser打开开发控制台,但是由于它是在我要调试的代码已经运行之后才开始播放的,所以我不知道在执行对话框时我能做些什么。 / p>
代码时间:
对话框按钮在清单中定义为
<ExtensionPoint xsi:type="MessageComposeCommandSurface">
...
<Action xsi:type="ExecuteFunction">
<FunctionName>showMessageDialog</FunctionName>
</Action>
运行:
function showMessageDialog(event) {
addinLogic.initializeMessage().done(function(messageItem) {
addinSessionStorage.setItem('CurrentAccount', Office.context.mailbox.userProfile.emailAddress);
addinSessionStorage.setItem(addinLogic.CurrentMessageItems, messageItem);
$.when(openDialogAsIframe('/dialogfile.html')).always(function(){ event.completed(); });
});
}
function openDialogAsIframe(dialogPage) {
var def = $.Deferred();
Office.context.ui.displayDialogAsync(
window.location.protocol + '//' + window.location.host + dialogPage,
{ height: 50, width: 75, displayInIframe: true }, dialogCallback.bind(def));
return def.promise();
}
此时,sessionstorage应该包含该对象,但是,启动对话框时,它返回并告诉我messageItem对象不存在。
(function () {
var _messageItem = null;
...
Office.onReady( function addinLevelsControllerInit(reason) {
app.initialize();
$(function () {
...
_messageItem = addinSessionStorage.getItem(addinLogic.CurrentMessageItems);
if (!_messageItem) {
Office.context.ui.messageParent('messageItem isnt there!');
return;
}
addinSessionStorage.getItem
基本上是window.sessionStorage || window.opener.sessionStorage || parent.window.opener.sessionStorage
到目前为止,获取任何信息的唯一方法是打开F12窗口以显示其他内容,并告诉它在发生任何异常时停止运行,这使我获得了类似于IE6级别的错误消息,而无法深入研究错误状态。
辛苦地使我能够将问题缩小到此处,现在我能想到的进一步调试的最佳方法是猜测工作和通过ui.messageParent
返回的消息。
如果只有一种方法可以将console.log重定向到文件。
-
edit:因此,即使我没有找到任何好的调试途径,我也一直到了某个地方。如果我将此对象写入localStorage,则插件可以正常工作,但是由于要处理敏感数据,因此永远无法将其保留在磁盘上。
既然从Outlook / IE的角度来看,功能区按钮和打开的对话框似乎在单独的会话中运行,那么我应该如何解决呢?
答案 0 :(得分:2)
我不确定它是否100%适用于您的情况:但是我过去用于“加载”问题的一种调试技巧是:
正常加载任务窗格/对话框。
附加Visual Studio(例如,按照https://docs.microsoft.com/en-us/office/dev/add-ins/testing/attach-debugger-from-task-pane上的说明进行操作)。在代码中找到您要设置断点的位置;或在代码本身内使用debugger;
关键字(请注意,由于未附加调试器,因此在加载外接程序时最初不会起作用;但是附加了调试器后,debugger;
关键字将作为自动断点)。
在出现的窗口中,输入window.location.reload()
并按Enter:
希望这会有所帮助!
〜迈克尔
答案 1 :(得分:0)
因为sessionStorage是唯一满足自动清除,最新且可在插件功能之间共享的存储位置;这是我所知道的唯一可行的选择。
但是在桌面Outlook上,会话并没有在所有部分之间共享,因为Outlook用于运行js插件的IE的行为就像在执行每个插件函数之后关闭了一样,从而清除了SessionStorage。
我相信我也找到了相关的文档-https://docs.microsoft.com/en-us/office/dev/add-ins/develop/dialog-api-in-office-add-ins#take-advantage-of-a-performance-option-in-office-online:"If the add-in is not running in Office Online, the displayInIframe is ignored."
这使得桌面Outlook在单独的窗口中打开我的对话框,因此
https://docs.microsoft.com/en-us/office/dev/add-ins/develop/dialog-api-in-office-add-ins#use-the-office-dialog-api-with-single-page-applications-and-client-side-routing "Important! The dialog box is in a new window with its own execution context ... Similarly, the dialog window has its own session storage, which is not accessible from code in the task pane."
结果,在我找到一种更好的插件间通信方法之前,我不得不在很长的时间里诉诸最丑陋的黑客之一:
Office.onReady(function(){
addinLocalStorage = new addinStorage('localStorage');
try { addinLocalStorage.setItem('_useSessionStorage', Office.context.mailbox.diagnostics.hostName != 'Outlook');
} catch (e) {}
if (addinLocalStorage.getItem('_useSessionStorage')) {
addinSessionStorage = new addinStorage('sessionStorage');
} else {
addinSessionStorage = new addinStorage('localStorage', 'ss_');
}
...
});
基本上,功能区按钮可以访问Office.context.mailbox
,因此可以将平台设置为localStorage。该对话框无权访问,这就是我被迫完全使用存储进行通信的全部原因,它可以读取localStorage并根据它来决定是否可以使用sessionStorage。>
现在剩下的就是找出可以从localStorage中删除的对象,以及应该离开的对象,以使数据永远不会保留在磁盘上。
哦,主题标题中的简短答案:否