Office ダイアログ API のベスト プラクティスとルール
この記事では、ダイアログの UI を設計し、単一ページ アプリケーション (SPA) 内で API を使用するためのベスト プラクティスなど、Office ダイアログ API のルール、概要、ベスト プラクティスについて説明します。
注:
Office ダイアログ API の使用の基本を理解するには、「Office アドインで Office ダイアログ API を使用する」を参照してください。
「 Office ダイアログ ボックスでのエラーとイベントの処理」も参照してください。
ルールと注意事項
ダイアログ ボックスは HTTP ではなく HTTPS URL にのみ移動できます。
displayDialogAsync メソッドに渡される URL は、アドイン自体とまったく同じドメインに存在する必要があります。 サブドメインにすることはできません。 ただし、渡されたページは、別のドメイン内のページにリダイレクトできます。
ホスト ページで一度に開くことができるダイアログ ボックスは 1 つだけです。 ホスト ページには、作業ウィンドウまたは関数コマンドの関数ファイルを指定できます。
ダイアログ ボックスで呼び出すことができる Office API は 2 つだけです。
- Office.context.ui.messageParent
-
Office.context.requirements.isSetSupported
(詳細については、「 Office アプリケーションと API の要件を指定する」を参照してください)。
messageParent 関数は通常、アドイン自体とまったく同じドメイン内のページから呼び出す必要がありますが、これは必須ではありません。 詳細については、「ホスト ランタイムへのクロスドメイン メッセージング」をご覧ください。
ヒント
Office on the web と 新しい Outlook on Windows では、ダイアログのドメインがアドインのドメインと異なり、 クロスオリジン-Opener-Policy: 同じ配信元 の応答ヘッダーが適用されている場合、アドインはダイアログからのメッセージへのアクセスをブロックされ、ユーザーに エラー 12006 が表示されます。 これを防ぐには、ヘッダーを
Cross-Origin-Opener-Policy: unsafe-none
に設定するか、アドインとダイアログが同じドメイン内に存在するように構成する必要があります。
ベスト プラクティス
ダイアログ ボックスを過度に使用しないようにする
UI 要素を重ねて表示することはお勧めできないため、シナリオで必要な場合を除き、作業ウィンドウでダイアログ ボックスを開かないようにします。 作業ウィンドウの表示領域の使用方法を検討するときには、作業ウィンドウはタブ表示できることに注意してください。 タブ付き作業ウィンドウの例については、 Excel アドイン JavaScript SalesTracker サンプルを参照してください。
ダイアログ ボックス UI をデザインする
ダイアログ ボックスのデザインのベスト プラクティスについては、「 Office アドインのダイアログ ボックス」を参照してください。
Office on the web でポップアップ ブロックを処理する
Office on the web の使用中にダイアログ ボックスを表示しようとすると、ブラウザーのポップアップ ブロックによってダイアログ ボックスがブロックされる可能性があります。 これを防ぐために、Office on the web は、ダイアログを開くことを 許可 または 無視 するようにユーザーに求めます。
ユーザーが [許可] を選択すると、[Office] ダイアログ ボックスが開きます。 ユーザーが [無視] を選択すると、プロンプトが閉じられ、[Office] ダイアログ ボックスが開きません。 代わりに、 displayDialogAsync
メソッドはエラー 12009 を返します。 コードでこのエラーをキャッチし、ダイアログを必要としない代替エクスペリエンスを提供するか、アドインでダイアログを許可する必要があることをユーザーに通知するメッセージを表示する必要があります。 (12009 の詳細については、「 displayDialogAsync からのエラー」を参照してください)。
何らかの理由でこの機能をオフにする場合は、コードをオプトアウトする必要があります。この要求は、displayDialogAsync
メソッドに渡される DialogOptions オブジェクトを使用して行います。 具体的には、オブジェクトに promptBeforeOpen: false
を含める必要があります。 このオプションが false に設定されている場合、Office on the web では、アドインによるダイアログの開き方をユーザーに求めず、Office ダイアログは開きません。
Office on the web と新しい Outlook on Windows のデバイス機能へのアクセスを要求する
アドインでユーザーのデバイス機能へのアクセスが必要な場合は、デバイスのアクセス 許可 API を使用してアクセス許可を要求するダイアログを使用できます。 デバイス機能には、ユーザーのカメラ、位置情報、マイクが含まれます。 これは、次の Office アプリケーションに適用されます。
- Microsoft Edge や Google Chrome などの Chromium ベースのブラウザーで実行されている 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 ではサポートされていません。
_host_info値を使用しない
Office は、_host_info
に渡される URL に displayDialogAsync
というクエリ パラメーターを自動的に追加します (カスタム クエリ パラメーターが存在する場合は、その後に追加されます。 カスタム クエリ パラメーター (存在する場合) の後に追加されます。 ダイアログ ボックスが移動する後続の URL には追加されません。 Microsoft は、この値の内容を変更したり、完全に削除したりして、コードが読み取られないようにすることができます。 ダイアログ ボックスのセッション ストレージ (つまり、 Window.sessionStorage プロパティ) にも同じ値が追加されます。 この場合も、コードではこの値に対する読み取りも書き込みも行わないでください。
閉じた直後に別のダイアログを開く
特定のホスト ページから複数のダイアログを開くことができないので、開いている ダイアログで Dialog.close を 呼び出してから、 displayDialogAsync
を呼び出して別のダイアログを開く必要があります。
close
メソッドは非同期です。 このため、close
の呼び出しの直後にdisplayDialogAsync
を呼び出した場合、Office が 2 番目のダイアログを開こうとしたときに、最初のダイアログが完全に閉じていない可能性があります。 その場合、Office から 12007 エラーが返されます。"このアドインには既にアクティブなダイアログがあるため、操作は失敗しました" というエラーが返されます。
close
メソッドはコールバック パラメーターを受け入れません。Promise オブジェクトは返されないため、await
キーワードまたは 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 ではなく、ルートの 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 ダイアログ API を使用している場合、SPA のインスタンスは実際には 1 つありません。
Office Add-ins