Office ダイアログ API のベスト プラクティスとルール

この記事では、ダイアログの UI を設計したり、単一ページ アプリケーション (SPA) 内で API を使用したりするためのベスト プラクティスなど、Office ダイアログ API のルール、制限事項、ベスト プラクティスについて説明します。

注:

Office ダイアログ API の使用の基本を理解するには、「 Office アドインで Office ダイアログ API を使用する」を参照してください。

「 Office ダイアログ ボックスを使用したエラーとイベントの処理」も参照してください。

ルールと制限事項

  • ダイアログ ボックスは、HTTP ではなく、HTTPS URL にのみ移動できます。

  • displayDialogAsync メソッドに渡す URL は、アドイン自体とまったく同じドメイン内にある必要があります。 サブドメインにすることはできません。 ただし、渡したページは、別のドメインのページにリダイレクトできます。

  • ホスト ページで一度に開くことができるダイアログ ボックスは 1 つだけです。 ホスト ページには、作業ウィンドウまたは関数コマンドの関数ファイルのいずれかを指定できます。 カスタム リボン ボタンまたはメニュー項目から、複数のダイアログを同時に開くことができます。

  • このダイアログ ボックスが呼び出せるのは、次の 2 つの Office API のみです。

  • 通常、 messageParent 関数はアドイン自体とまったく同じドメインのページから呼び出しますが、これは必須ではありません。 詳細については、「ホスト ランタイムへのクロスドメイン メッセージング」をご覧ください。

  • ダイアログ ボックスを開くと、Office アプリケーションの上部の画面中央に表示されます。

  • ユーザーはダイアログ ボックスを移動したりサイズを変更したりできます。

  • ダイアログ ボックスが作成された順に表示されます。

    ヒント

    Office on the web と新しい Outlook on Windows では、ダイアログのドメインがアドインのドメインと異なり、Cross-Origin-Opener-Policy: same-origin 応答ヘッダーを強制する場合、アドインはダイアログからのメッセージへのアクセスからブロックされ、ユーザーにエラー 12006 が表示されます。 このエラーを防ぐには、ヘッダーを Cross-Origin-Opener-Policy: unsafe-none に設定するか、アドインとダイアログが同じドメイン内になるように構成します。

  • Windows 上の Outlook on the web および新しい Outlook では、アドインでダイアログを構成するときに window.name プロパティを設定しないでください。 これらの Outlook クライアントは、 window.name プロパティを使用して、ページ リダイレクト間で機能を維持します。

ベスト プラクティス

ダイアログ ボックスの使いすぎを避ける

UI 要素を重ねて表示することはお勧めできないため、シナリオで必要な場合を除き、作業ウィンドウでダイアログ ボックスを開かないようにします。 作業ウィンドウの表示領域の使用方法を検討するときには、作業ウィンドウはタブ表示できることに注意してください。

ダイアログ ボックス UI をデザインする

ダイアログ ボックスの設計におけるベスト プラクティスについては、「 Office アドインのダイアログ ボックス」を参照してください。

Office on the web でポップアップ ブロックを処理する

Office on the web の使用中にダイアログ ボックスを表示しようとすると、ブラウザーのポップアップ ブロックがダイアログ ボックスをブロックする可能性があります。 この問題を防ぐために、Office on the web は、ダイアログを開くことを許可するか無視するかをユーザーに求めます。

簡単な説明およびブラウザー内のポップアップ ブロックを回避するためにアドインが生成できる [許可] ボタンと [無視] ボタンを含むプロンプト。

ユーザーが [許可] を選択すると、[Office] ダイアログ ボックスが開きます。 ユーザーが [無視] を選択すると、プロンプトが閉じ、Office ダイアログ ボックスは開きません。 代わりに、 displayDialogAsync メソッドはエラー 12009 を返します。 コードでこのエラーをキャッチし、ダイアログを必要としない代替エクスペリエンスを提供するか、アドインがダイアログを許可する必要があることをユーザーに通知するメッセージをユーザーに表示する必要があります。 エラー 12009 の詳細については、「 displayDialogAsync からのエラー」を参照してください。

ブロックされたダイアログを処理する (エラー 12009)

アドインは常にエラー 12009 を適切に処理する必要があります。 推奨される方法をいくつか紹介します。

  • ダイアログが必要な理由を説明するユーザー フレンドリーなメッセージを表示します。

    Office.context.ui.displayDialogAsync(
      "https://www.contoso.com/auth.html",
      { height: 60, width: 30 },
      (asyncResult) => {
        if (asyncResult.status === Office.AsyncResultStatus.Failed) {
          if (asyncResult.error.code === 12009) {
            // User blocked the dialog.
            showNotification(
              "Dialog Required",
              "This add-in needs to open a dialog to sign you in. " +
              "Please click the add-in button again and choose 'Allow' when prompted."
            );
          } else {
            // Handle other errors.
            showNotification("Error", `Unable to open dialog: ${asyncResult.error.message}`);
          }
        } else {
          // Dialog opened successfully.
          const dialog = asyncResult.value;
          // ... Handle dialog events here.
        }
      }
    );
    
  • 可能な場合は、代替ワークフローを提供します。 ダイアログがブロックされたときに機能を制限してもアドインが機能する場合は、その代替手段をユーザーに提供します。

プロンプトを無効にする

許可/無視のプロンプトをオフにする場合は、コードでオプトアウトする必要があります。この要求は、displayDialogAsync メソッドに渡す DialogOptions オブジェクトを使用して行います。 具体的には、オブジェクトに promptBeforeOpen: false を含めます。 このオプションを false に設定すると、アドインによるダイアログのオープンをユーザーに求めるプロンプトは Office on the web で表示されず、ブラウザーのポップアップ ブロックによってブロックされる場合は Office ダイアログは開きません。

注:

ほとんどのシナリオでは、 promptBeforeOpen: false 設定することはお勧めしません。 ユーザーに確認を求める既定の動作では、ユーザー エクスペリエンスが向上し、ユーザーがダイアログが必要な理由を理解できるようにします。

Office on the web と新しい Outlook on Windows のデバイス機能へのアクセスを要求する

アドインがユーザーのデバイス機能にアクセスする必要がある場合は、 デバイスアクセス許可 API を使用して、ダイアログを通じてアクセス許可を要求します。 デバイス機能には、ユーザーのカメラ、位置情報、マイクが含まれます。 この要件は、次の Office アプリケーションに適用されます。

  • Microsoft Edge や Google Chrome などの Chromium ベースのブラウザーで実行されている Office on the web (Excel、Outlook、PowerPoint、および Word)
  • Windows 上の新しい Outlook

アドインが Office.context.devicePermission.requestPermissions または Office.context.devicePermission.requestPermissionsAsync を呼び出すと、要求されたデバイス機能と、[ 許可]、[ 1 回許可]、または [アクセス を拒否 ] のオプションを含むダイアログが表示されます。 詳細については、「Excel、PowerPoint、Word のアドインを表示、管理、インストールする」を参照してください。

注:

  • Office デスクトップ クライアントまたは Chromium ベースではないブラウザーで実行されるアドインでは、ユーザーのアクセス許可を求めるダイアログが自動的に表示されます。 開発者は、これらのプラットフォームにデバイスアクセス許可 API を実装する必要はありません。
  • Safari で実行されるアドインは、ユーザーのデバイス機能へのアクセスからブロックされます。 デバイスアクセス許可 API は Safari ではサポートされていません。
  • ユーザーの位置情報へのアクセスは、Outlook on the web と新しい Outlook on Windows でのみサポートされます。

_host_info 値は使用しないでください

Office は、displayDialogAsync に渡される URL に _host_info という名前のクエリ パラメーターを自動的に追加します。 カスタム クエリ パラメーター (存在する場合) の後にこのパラメーターが追加されます。 このパラメーターは、ダイアログ ボックスが移動する後続の URL には付加されません。 Microsoft によってこの値の内容が変更されたり、完全に削除されたりする可能性があるため、コードで読み取らないでください。 同じ値がダイアログ ボックスのセッション ストレージ ( つまり、Window.sessionStorage プロパティ) に追加されます。 この場合も、コードではこの値に対する読み取りも書き込みも行わないでください。

ダイアログを閉じた直後に別のダイアログを開く

特定のホスト ページから複数のダイアログを開くことはできません。このため、コードでは、別のダイアログを開くために displayDialogAsync を呼び出す前に、開いているダイアログで Dialog.close を呼び出す必要があります。 close メソッドは非同期です。 このため、close の呼び出しの直後に displayDialogAsync を呼び出すと、Office が 2 番目のダイアログを開こうとしたときに最初のダイアログが完全に閉じられないことがあります。 このような場合、Office は 12007 エラーを返します。"このアドインには既にアクティブなダイアログがあるため、操作に失敗しました。"

close メソッドはコールバック パラメーターを受け入れず、Promise オブジェクトを返さないので、await キーワード (keyword) または then メソッドを使用して待機することはできません。 このため、ダイアログを閉じた直後に新しいダイアログを開く必要がある場合は、次の方法を使用します。関数で新しいダイアログを開くためのコードをカプセル化し、 displayDialogAsync の呼び出しで 12007 が返された場合は再帰的に自身を呼び出すように関数を設計します。 次の例は、この手法を実装する方法を示しています。

function openFirstDialog() {
  Office.context.ui.displayDialogAsync(
    "https://MyDomain/firstDialog.html",
    { width: 50, height: 50 },
    (result) => {
      if (result.status === Office.AsyncResultStatus.Succeeded) {
        const dialog = result.value;
        dialog.close();
        openSecondDialog();
      }
      else {
         // Handle errors.
      }
    }
  );
}
 
function openSecondDialog() {
  Office.context.ui.displayDialogAsync(
    "https://MyDomain/secondDialog.html",
    { width: 50, height: 50 },
    (result) => {
      if (result.status === Office.AsyncResultStatus.Failed) {
        if (result.error.code === 12007) {
          openSecondDialog(); // Recursive call.
        }
        else {
         // Handle other errors.
        }
      }
    }
  );
}

または、 setTimeout メソッドを使用して、2 番目のダイアログを開こうとする前にコードを強制的に一時停止させることもできます。 次の例は、この方法を実装する方法を示しています。

function openFirstDialog() {
  Office.context.ui.displayDialogAsync(
    "https://MyDomain/firstDialog.html",
    { width: 50, height: 50 },
    (result) => {
      if (result.status === Office.AsyncResultStatus.Succeeded) {
        const dialog = result.value;
        dialog.close();
        setTimeout(() => { 
          Office.context.ui.displayDialogAsync(
            "https://MyDomain/secondDialog.html",
            { width: 50, height: 50 },
            (result) => {
              // Callback body.
            }
          );
        }, 1000);
      }
      else {
         // Handle errors.
      }
    }
  );
}

SPA で Office ダイアログ API を使うためのベスト プラクティス

シングルページ アプリケーション (SPA) が通常行うように、アドインでクライアント側ルーティングを使用する場合は、別の HTML ページの URL の代わりに displayDialogAsync メソッドにルートの URL を渡すことができます。 次のセクションで説明する理由で、この方法は使用しないでください。

注:

この記事は、Express ベースの Web アプリケーションなどの サーバー側 ルーティングとは関連ありません。

SPA と Office ダイアログ API に関する問題

Office ダイアログ ボックスは、JavaScript エンジンの独自のインスタンスを含む新しいウィンドウに表示されるため、独自の完全な実行コンテキストがあります。 ルートを渡すと、ベース ページとそのすべての初期化およびブートストラップ コードがこの新しいコンテキストで再び実行され、ダイアログ ボックスで変数が初期値に設定されます。 そのため、この手法では、ダイアログ ボックス ウィンドウでアプリケーションの 2 番目のインスタンスをダウンロードして起動し、SPA の目的を部分的に無効にします。 さらに、ダイアログ ボックス ウィンドウの変数を変更するコードでは、同じ変数の作業ウィンドウ バージョンは変更されません。 同様に、ダイアログ ボックス ウィンドウには独自のセッション ストレージ ( Window.sessionStorage プロパティ) がありますが、これは作業ウィンドウのコードからはアクセスできません。 displayDialogAsyncが呼び出されたダイアログ ボックスとホスト ページは、サーバーにとって 2 つの異なるクライアントのように見えます。 (ホスト ページの概要については、「 ホスト ページからダイアログ ボックスを開く」を参照してください。)

そのため、ルートを displayDialogAsync メソッドに渡す場合、実際には SPA は存在せず、 同じ SPA の 2 つのインスタンスがあります。 さらに、作業ウィンドウ インスタンス内のコードの多くはそのインスタンスでは使用されません。また、ダイアログ ボックス インスタンス内のコードの多くがそのインスタンスで使用されることはありません。 これは、同じバンドルに 2 つの SPA があるようなものです。

Microsoft の推奨事項

クライアント側のルートを displayDialogAsync メソッドに渡す代わりに、次のいずれかの方法を使用します。

  • ダイアログ ボックスで実行するコードが十分に複雑な場合は、2 つの異なる SPA を明示的に作成します。つまり、同じドメインの異なるフォルダーに 2 つの SPA があります。 一方の SPA はダイアログ ボックスで実行され、もう 1 つは displayDialogAsync が呼び出されたダイアログ ボックスのホスト ページで実行されます。
  • ほとんどのシナリオでは、ダイアログ ボックスに必要なのは単純なロジックのみです。 このような場合、SPA のドメインで埋め込まれた、または参照された JavaScript を使用して単一の HTML ページをホストすることで、プロジェクトが大幅に簡素化されます。 ページの URL を displayDialogAsync メソッドに渡します。 このアプローチは、文字通りのシングルページ アプリの概念から逸脱することを意味しますが、Office ダイアログ API を使用する場合、実際には SPA の単一のインスタンスはありません。

関連項目