Office.js аннулирует функции истории браузера, использующие использование истории

Официальная версия office.js доступна здесь:

https://appsforoffice.microsoft.com/lib/1/hosted/office.js

Он содержит следующие строки в коде:

window.history.replaceState = null;
window.history.pushState = null;

Это нарушает некоторые функции истории в моих надстройках Excel (я использую react и react-router)

Почему office.js сбрасывает эти функции истории? Я не могу найти никаких объяснений в документации.

Ответ 1

Элемент управления браузером, используемый в Excel, не поддерживает API истории, если replaceState и pushState не были исключены, они будут доступны для реагирования, но всегда будут вызывать исключение при вызове. До тех пор, пока не будет доступен новый элемент управления браузером, вам нужно будет перейти на хэш-маршрутизацию или использовать polyfill для API истории. https://github.com/devote/HTML5-History-API, похоже, работает, если вы включили ссылку script после office.js.

Ответ 2

Это работает для меня - кешируйте объекты до того, как office-js их удалит:

<script type="text/javascript">
    // Office js deletes window.history.pushState and window.history.replaceState. Cache them and restore them
    window._historyCache = {
        replaceState: window.history.replaceState,
        pushState: window.history.pushState
    };
</script>

<script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>

<script type="text/javascript">
    // Office js deletes window.history.pushState and window.history.replaceState. Restore them
    window.history.replaceState = window._historyCache.replaceState;
    window.history.pushState = window._historyCache.pushState;
</script>

Ответ 3

Моя версия Windows 10 Pro, браузер по умолчанию Edge 42.17134.1.0. Но правая боковая панель, где Outlook запускает надстройку, использует старый механизм IE10; ((IE10 как браузер также есть в Windows). Я не знаю, это верно для всех Windows или это какой-то особый случай для моей версии. IE10 поддерживает history.replaceState и history.pushState, но внутри Outlook у меня есть проблемы с этими методами, поэтому простое восстановление не работает для меня.

Простое решение с кешем history.replaceState и history.pushState не работает для меня. В Outlook с IE10 внутри у меня возникает неожиданная ошибка, когда мой код вызывает history.replaceState или history.pushState. Но я нашел одну интересную вещь. Если подавить ошибку, они делают свою работу.

Итак, мой обходной путь:

 function isIE10 () {
      return !!document.documentMode
    }

    // Office js deletes window.history.pushState and window.history.replaceState. Cache them and restore them
    // Also there is an issue in Windows Outlook with 'pushState' and 'replaceState'. They throw an error but in the same time do their expected work
    // So I suppress errors for IE10 (we use it inside Window Outlook)
    window._historyCache = {
      replaceState: function (originalReplaceState) {
        return function () {
          try {
            return originalReplaceState.apply(window.history, arguments)
          } catch (e) {
            if (isIE10()) {
              console.warn("Unexpected error in 'window.history.replaceState', but we can continue to work :)");
              return false;
            }
            throw(e);
          }
        }
      }(window.history.replaceState),
      pushState: function (originalFunction) {
        return function () {
          try {
            return originalFunction.apply(window.history, arguments)
          } catch (e) {
            if (isIE10()) {
              console.warn("Unexpected error in 'window.history.pushState', but we can continue to work :)");
              return false;
            }
            throw(e);
          }
        }
      }(window.history.pushState)
    };

      // In Window Outlook we have issue with 'replaceState' and 'pushState. So replaced it by wrapped version.
      window.history.replaceState = window._historyCache.replaceState;
      window.history.pushState = window._historyCache.pushState;

//include the main code with react-router
//include Office.js


   Office.initialize = function () {

    // Office js deletes window.history.pushState and window.history.replaceState. Restore them
    window.history.replaceState = window._historyCache.replaceState;
    window.history.pushState = window._historyCache.pushState;

    // Now you can start initialize&&run your application
        ....
   }

Примечание. Я должен заменить history.replaceState и history.pushState перед запуском любого кода, который работает с этим API. В моем случае это реагирует на роутер.