次の方法で共有


Office Dialog API のベスト プラクティスとルール

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

注:

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

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

規則と制限事項

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

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

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

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

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

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

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

  • ダイアログ ボックスは、作成された順序で表示されます。

    ヒント

    Office on the webおよび新しい Outlook on Windows では、ダイアログのドメインがアドインのドメインと異なり、クロスオリジン-Opener-Policy: 同じ配信元の応答ヘッダーが適用されている場合、アドインはダイアログからのメッセージへのアクセスをブロックされ、ユーザーにエラー 12006 が表示されます。 このエラーを回避するには、ヘッダーを Cross-Origin-Opener-Policy: unsafe-none に設定するか、アドインとダイアログが同じドメイン内にあるよう構成します。

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

ベスト プラクティス

ダイアログ ボックスを過度に使用しないようにする

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

ダイアログ ボックス 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 アプリケーションに適用されます。

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

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

注:

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

_host_info値を使用しない

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

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

特定のホスト ページから複数のダイアログを開くことができないので、開いている ダイアログで Dialog.close を 呼び出してから、 displayDialogAsync を呼び出して別のダイアログを開く必要があります。 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 Dialog API を使用するためのベスト プラクティス

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

注:

この記事は、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 を配置します。 1 つの SPA はダイアログ ボックスで実行され、もう 1 つはダイアログ ボックスのホスト ページで実行され、もう 1 つは displayDialogAsync が呼び出されました。
  • ほとんどのシナリオでは、ダイアログ ボックスには単純なロジックのみが必要です。 このような場合、SPA のドメインに埋め込みまたは参照される JavaScript を含む 1 つの HTML ページをホストすることで、プロジェクトが大幅に簡略化されます。 ページの URL を displayDialogAsync メソッドに渡します。 この方法は、単一ページ アプリの文字通りの考え方から逸脱していることを意味しますが、Office Dialog API を使用する場合、SPA のインスタンスは実際には 1 つありません。

関連項目