Можно ли использовать sessionStorage для надстроек к outlook-js на рабочем столе?

TL;DR

Я использую sessionStorage для связи между различными частями надстройки, кода, выполняемого при нажатии кнопки ленты в окне создания, и диалогового окна, которое оно открывает. Это работает в браузере, но на рабочем столе Outlook SessionStorage в диалоговом окне пусто. Что дает?

// TL;DR

Я создал js-надстройку, которая отлично работает в браузере в Интернете, но ужасно сломана на рабочем столе. Я бы предпочел полностью отключить его на рабочем столе, поскольку есть надстройка VSTO, которая делает гораздо больше, чем способен js api, но, поскольку я не нашел способа сделать это, мой единственный вариант теперь выглядит так: make версия JS работает во всем мире.

Я обнаружил, что на рабочем столе работает IE всех "браузеров", и я довольно далеко отлаживал надстройку с помощью IE на outlook.com, однако у меня закончились синтаксические ошибки, и теперь я столкнулся с проблемой, которая только представляет Сам по себе на рабочем столе.

Основная идея такова: когда пользователь запускает это действие, я хочу создать объект в sessionStorage, если он не существует. Затем диалоговое окно прочитает объект и предоставит пользователю форму, после отправки этот объект обновится, настройки будут применены, и диалоговое окно закроется. По какой-то причине на рабочем столе Outlook, когда диалоговое окно запускается, sessionStorage для этого ключа имеет значение null, тогда как в браузере (даже с IE) он правильно инициализирован.

Я попытался открыть консоль разработчика с помощью F12Chooser, но, поскольку она начинает играть после того, как код, который я хочу отладить, уже запущен, я не знаю, что я могу сделать, чтобы перехватить диалоговое окно во время его выполнения.

время кода:

диалоговая кнопка определяется в манифесте как

<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 в файл..

-

редактировать: так что я добираюсь куда-то, хотя я не нашел хороших путей отладки. Если я записываю этот объект в localStorage, надстройка работает нормально, но, поскольку обрабатываются конфиденциальные данные, невозможно оставить их на диске навсегда.

Как мне тогда исправить это, поскольку кажется, что кнопка ленты и открытое диалоговое окно выполняются в отдельных сеансах с точки зрения Outlook/IE?

2 ответа

Решение

Поскольку sessionStorage является единственным хранилищем, отвечающим требованиям автоматической очистки, актуальным и совместным с функциями надстройки; это единственный жизнеспособный выбор, о котором я знаю.

В настольном Outlook, однако, сеансы не разделяются между всеми частями, так как IE, который использует внешний вид для запуска надстроек js, ведет себя так, как если бы он был закрыт после выполнения каждой функции надстройки, таким образом очищая sessionStorage.

Я считаю, что я также нашел соответствующие фрагменты документации - https://docs.microsoft.com/en-us/office/dev/add-ins/develop/dialog-api-in-office-add-ins: "If the add-in is not running in Office Online, the displayInIframe is ignored." Что делает внешний вид рабочего стола открывать мой диалог в отдельном окне, таким образом https://docs.microsoft.com/en-us/office/dev/add-ins/develop/dialog-api-in-office-add-ins "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, а какие оставить, чтобы данные не оставались на диске навсегда.

Да, и краткий ответ на вопрос в заголовке темы: НЕТ

Я не уверен, что это на 100% применимо к вашему случаю: но одна хитрость отладки, которую я использовал в прошлом для проблем "под нагрузкой", заключается в следующем:

  1. Пусть панель задач / диалог загружается нормально.

  2. Присоедините Visual Studio (например, используя инструкции по адресу https://docs.microsoft.com/en-us/office/dev/add-ins/testing/attach-debugger-from-task-pane). Найдите в коде место, где вы хотите установить точку останова; или используйте debugger; ключевое слово в самом коде (обратите внимание, что оно изначально не будет действовать, когда ваша надстройка загружается, потому что отладчик не подключен; но как только отладчик подключен, debugger; ключевое слово будет действовать как автоматическая точка останова).

  3. В меню "Быстрый запуск" в правом верхнем углу Visual Studio запустите "Консоль JavaScript"

  4. В появившемся окне введите window.location.reload() и нажмите ввод:

  1. Теперь ваши точки останова должны перехватываться - и вы должны иметь возможность отлаживать логику запуска.

Надеюсь это поможет!

~ Майкл

Другие вопросы по тегам