Web Share API

W3C 勧告

この文書についての詳細
このバージョン:
https://www.w3.org/TR/2023/REC-web-share-20230530/
最新公開バージョン:
https://www.w3.org/TR/web-share/
最新エディタ草案:
https://w3c.github.io/web-share/
履歴:
https://www.w3.org/standards/history/web-share
コミット履歴
テストスイート:
https://wpt.live/web-share/
実装報告:
https://w3c.github.io/web-share/imp-report/
編集者:
Matt Giuca (Google Inc.)
Eric Willigers (Google Inc.)
Marcos Cáceres (Apple Inc.)
フィードバック:
GitHub w3c/web-share (プルリクエスト, 新規 issue, オープン issue)
正誤表:
正誤情報あり
ブラウザー対応:
caniuse.com

関連情報 翻訳.


概要

この仕様は、テキスト、リンク、その他のコンテンツをユーザーが選択した任意の送信先に共有するためのAPIを定義します。

利用可能な共有先はこの仕様では指定されていません。ユーザーエージェントが提供します。例えば、アプリ、ウェブサイト、連絡先などが考えられます。

この文書のステータス

このセクションは、本書が公開された時点での文書のステータスについて説明します。現行の W3C 公開文書の一覧と、この技術レポートの最新版は W3C 技術レポート一覧 https://www.w3.org/TR/ で確認できます。

本書は Web Applications Working Group により 勧告プロセスに則って 勧告として公開されました。

W3C は本仕様のWeb標準としての広範な展開を推奨します。

W3C 勧告は、十分な合意形成の後に W3C およびそのメンバーによって支持され、 ワーキンググループのメンバーが ロイヤリティフリーライセンス へのコミットメントを行った仕様です。 今後の勧告の更新には 新機能 が組み込まれる可能性があります。

本書は W3C 特許ポリシーの下で活動するグループにより作成されています。 W3Cグループ関連公開特許情報リスト を管理しており、そのページには特許の公開方法も記載されています。特許の実質的な請求項が含まれると考えられる特許を知っている場合は、 W3C特許ポリシー第6節に従って情報を開示する必要があります。

この文書は 2021年11月2日 W3C プロセス文書によって管理されています。

実装状況

このセクションは規範的ではありません。

コンテンツ共有機能は、基盤となるオペレーティングシステムが「共有」機能を提供していること、およびOSのUI慣習に依存することが多いです。例えば、一部のOSでは「共有シート」が表示され、他のOSではポップアップメニューが使われます。これらの依存性により、Web Share APIをすべてのOSで利用可能にするために実装者による継続的な取り組みが行われています。この進行中の取り組みは、限られたOSでテストを実行して生成される実装報告に失敗として反映されています。ただし、ワーキンググループはWeb Share APIが今後さらに多くのOSで利用できるようになり、すでに幅広いデバイスの主要なOSで広く利用可能になっていることに楽観的です。

1. 使用例

このセクションは規範的ではありません。

1.2 ファイルの共有

この例はファイルを共有する方法を示します。files メンバーは配列であり、複数のファイルを共有できます。

2: ファイルの共有
shareButton.addEventListener("click", async () => {
  const file = new File(data, "some.png", { type: "image/png" });
  try {
    await navigator.share({
      title: "Example File",
      files: [file]
    });
  } catch (err) {
    console.error("Share failed:", err.message);
  }
});

1.3 共有の検証

canShare() メソッドに ShareData 辞書を渡すと、共有データの 検証が行われます。share() と異なり、一時的なアクティベーションなしで呼び出すことができます。

const file = new File([], "some.png", { type: "image/png" });

// ファイルがサポートされているか確認
if (navigates.canShare({files: [file]})) {
  // pngファイルの共有はおそらく可能です...
}

// URLの共有が可能か確認
if (navigates.canShare({ url: someURL })) {
  // URLは有効で、共有可能です...
}

1.4 メンバーのサポート状況の確認

WebIDL辞書の仕様により、share() にユーザーエージェントが認識しないメンバーを渡した場合、それらは無視されます。 複数のメンバーを共有する際、ユーザーエージェントが一部のメンバーをサポートしない場合は問題となることがあります。すべてのメンバーがサポートされていることを確認したい場合は、canShare() に個別に渡してサポートされているか確認できます。

4: 共有の将来対応
const data = {
  title: "Example Page",
  url: "https://example.com",
  text: "This is a text to share",
  someFutureThing: "some future thing",
};
const allSupported = Object.entries(data).every(([key, value]) => {
  return navigator.canShare({ [key]: value });
});
if (allSupported) {
  await navigator.share(data);
}

または、サポートされていないメンバーのUIコンポーネントを表示しないようにアプリケーションのUIを調整することもできます。

5: サポートされていないメンバーの除外
const data = {
  title: "Example Page",
  url: "https://example.com",
  text: "This is a text to share",
  someFutureThing: "some future thing",
};

// サポートされていないもの...
const unsupported = Object.entries(data).filter(([key, value]) => {
  return !navigator.canShare({ [key]: value });
});

1.5 サードパーティコンテキストでのAPI有効化

デフォルトの許可リストである 'self' により、Web Share APIはデフォルトでファーストパーティコンテキストでのみ利用可能です。

サードパーティは、iframeallow 属性を使って、このAPIの利用を許可できます:

また、ファーストパーティコンテキストでAPIを無効化するには、HTTPレスポンスヘッダーを指定します:

詳細やオリジンごとのパーミッションポリシーの制御方法については Permissions Policy 仕様をご参照ください。

2. API定義

2.1 Navigator インターフェイスへの拡張

WebIDLpartial interface Navigator {
  [SecureContext] Promise<undefined> share(optional ShareData data = {});
  [SecureContext] boolean canShare(optional ShareData data = {});
};

2.1.1 内部スロット

このAPIは Navigator インターフェイスに以下の内部スロットを追加します。

Promise? [[sharePromise]]
this.[[sharePromise]] は、ユーザーが現在データを 共有先 に共有しようとする意図を表すPromiseです。初期値は null です。

2.1.2 share() メソッド

share() メソッドが data 引数付きで呼び出された場合、以下のステップをセキュリティ上の注意事項も考慮しながら実行します。

Web Shareはウェブサイトから共有先(ネイティブアプリ等)へデータを送信できる機能を提供します。この機能はWeb Share固有ではありませんが、プラットフォームによって深刻度が異なるさまざまなセキュリティリスクを伴います。

share() に渡されたデータは、 共有先のバッファオーバーフローやリモートコード実行脆弱性の悪用に使われる可能性があります。一般的な対策はありませんが、特にファイル共有時には実装者はこの可能性を認識しておくべきです。

共有先が共有されたURLを解決して情報転送する場合、機密情報が漏洩する可能性があります。共有が参照するコンテンツが、そのアプリやホスト、ネットワークロケーションでのみアクセス可能な場合、意図しない情報漏洩につながることがあります。

悪意あるサイトは、最終的にローカルリソース("file:" URL やローカルサービス等)に解決されるURLを提供することで、情報漏洩する共有先を悪用する可能性があります。このAPIは共有可能なスキームを制限しますが、リダイレクトやDNSレコードの操作によって、アプリがコンテンツを取得させられる可能性もあります。

このような攻撃への対策として、共有先はURLを取得して処理するのみで他へ共有しないようにできます。たとえば、画像編集アプリが共有された画像のみ取得する場合や、URLだけ共有して内容を取得しない場合などです。

プレビューや共有のためにコンテンツを取得する共有先は、情報漏洩リスクがあります。ユーザーがプレビューや許可した内容なら安全ですが、機密性の判断が難しい場合もあり、内容の転送はリスクを伴います。特に、title は攻撃者がユーザーを誤認させるために利用する可能性があります(5. アクセシビリティに関する考慮事項も参照)。

DOMException を使用する場合、実装者は share() の拒否時にエラーメッセージでどの情報が公開されるか慎重に検討する必要があります。共有先がない場合とユーザーキャンセルの場合を区別するだけでも、デバイスにどの共有先がインストールされているかが漏洩する可能性があります。

  1. globalthis関連グローバルオブジェクトとします。
  2. documentglobal関連付けられた Documentとします。
  3. document完全にアクティブでない場合、promiseを拒否し "InvalidStateError" DOMException を返します。
  4. document"web-share" を使用許可されていない場合、promiseを拒否し "NotAllowedError" DOMException を返します。
  5. this.[[sharePromise]]null でない場合、promiseを拒否し "InvalidStateError" DOMException を返します。
  6. global一時的なアクティベーションを持たない場合、promiseを拒否し "NotAllowedError" DOMException を返します。
  7. globalのユーザーアクティベーションを消費します。
  8. basethis関連設定オブジェクトAPIベースURL とします。
  9. validate share datadatabase で実行した結果が false の場合、promiseを拒否TypeError を返します。
  10. dataurl メンバーが存在する場合:
    1. urlURL パーサーdataurlbase を使って実行した結果とします。
    2. Assert: urlURL です。
    3. data をコピーし、その url メンバーに urlURLシリアライザー でシリアライズした結果を設定します。
  11. セキュリティ上の理由でファイルタイプがブロックされている場合、promiseを拒否し "NotAllowedError" DOMException を返します。
  12. this.[[sharePromise]]新しいPromise をセットします。
  13. this.[[sharePromise]] を返し、並行して
    1. 利用可能な 共有先 がない場合、グローバルタスクをキューし、ユーザーインタラクションタスクソースglobal で使用して:
      1. reject this.[[sharePromise]] を "AbortError" DOMException で拒否します。
      2. this.[[sharePromise]]null に設定します。
      3. このアルゴリズムを終了します。
    2. ユーザーに1つ以上の 共有先 の選択肢と操作中止の選択肢を提示します。このUIはセキュリティ確認の役割を持ち、ウェブサイトがデータをネイティブアプリへ密かに送信できないようにします。ユーザーエージェントはOSレベルUIでこの機能がない場合、中間UIを表示してユーザーが共有内容を確認できるように 推奨 します。
    3. ユーザーの選択を待ちます。
    4. ユーザーが共有操作を中止した場合は、グローバルタスクをキューユーザーインタラクションタスクソースglobal で使用して:
      1. reject this.[[sharePromise]] を "AbortError" DOMException で拒否します。
      2. this.[[sharePromise]]null に設定します。
      3. このアルゴリズムを終了します。
    5. 選択された 共有先 を起動し、dataを共有先向けの形式に変換し、変換したデータを送信します。
    6. 共有先の起動やデータ送信でエラーが発生した場合は、グローバルタスクをキューユーザーインタラクションタスクソースglobal で使用して:
      1. reject this.[[sharePromise]] を "DataError" DOMException で拒否します。
      2. this.[[sharePromise]]null に設定します。
      3. このアルゴリズムを終了します。
    7. データが 共有先 に正常に送信された場合、またはOSに正常に送信された場合(共有先への送信可否が確認できない場合)、グローバルタスクをキューユーザーインタラクションタスクソースglobal で使用して:
      注記
      1. resolve this.[[sharePromise]]undefined で解決します。
      2. this.[[sharePromise]]null に設定します。

2.1.3 canShare(data) メソッド

canShare() メソッドが ShareData data 引数付きで呼び出された場合、次の手順を実行します:

  1. documentthis関連グローバルオブジェクト関連付けられた Document とします。
  2. document完全にアクティブでない場合、false を返します。
  3. document"web-share" を使用許可されていない場合、false を返します。
  4. validate share datadatathis関連設定オブジェクトAPIベースURL で実行した結果を返します。
注記: canShare() は将来互換性がない

2.1.4 共有データの検証

共有可能なスキーム とは、以下の URL スキーム のいずれかです:

共有データの検証database で実行するには、次の手順を実行します:

  1. datatitle, texturlfiles のいずれも存在しない場合、false を返します。
  2. titletexturl のいずれかが存在する場合、titleTextOrUrl を true とします。
  3. datafiles メンバーが存在する場合:
    1. titleTextOrUrl が false で、datafiles メンバーが空の場合、false を返します。
      注記

      { files: [] } のような辞書は空辞書として扱われます。ただし {text: "text", files: []} のような辞書は、files が単に無視されるだけなので問題ありません。

    2. 実装がファイル共有をサポートしていない場合、false を返します。
    3. ユーザーエージェントが files 内のいずれかのファイルが悪意ある共有(内容・サイズ・その他特徴によって悪意があると判断した場合)になると考える場合、false を返します。
  4. dataurl メンバーが存在する場合:
    1. urlURLパーサーdataurl メンバーと base を使い、エンコーディングオーバーライド無しで実行した結果とします。
    2. url が失敗の場合、false を返します。
    3. urlスキームローカルスキームfilejavascriptwswss のいずれかの場合、false を返します。
    4. urlスキーム共有可能なスキーム でない場合、false を返します。
  5. true を返します。

2.2 ShareData 辞書

WebIDLdictionary ShareData {
  sequence<File> files;
  USVString title;
  USVString text;
  USVString url;
};

ShareData 辞書は複数のオプションのメンバーで構成されています:

files メンバー
共有するファイル。
text メンバー
共有されるメッセージ本文となる任意のテキスト。
title メンバー
共有される文書のタイトル。共有先によっては無視される場合があります。
url メンバー
共有されるリソースを指すURL文字列。
注記

3. 共有先

共有先とは、ユーザーエージェントが共有データを送信する抽象的な送信先の概念です。何が共有先になるかはユーザーエージェントの裁量によります。

共有先は必ずしも ShareData を直接受け取れるとは限りません(このAPIを前提に作られていない場合)。しかし、MUST ShareData で公開される概念の一部または全部に合致するデータを受け取れる能力を持っていなければなりません。共有先向けにデータを適切な形式に変換するために、ユーザーエージェントは SHOULD ShareData のメンバーを共有先の同等の概念にマッピングします。必要に応じてメンバーを破棄したり結合しても MAY です。ペイロードの各メンバーの意味は共有先の裁量です。

注記
ShareData を共有先やOSのネイティブ形式にマッピングするのは、プラットフォームによっては同等のメンバーが存在しないため難しい場合があります。例えば、ターゲットが「text」メンバーしか持たず「URL」メンバーを持たない場合(Androidなど)、texturl を連結してターゲットの「text」メンバーに渡すという解決策が考えられます。

各共有先は、ShareData ペイロードの内容によって条件付きで利用可能になることが MAY です。これは share() メソッドに渡されたペイロードに依存します。

3.1 共有先の例

このセクションは規範的ではありません。

共有先のリストは、ユーザーエージェントやホストOSによってさまざまなソースから構築されます。例:

注記
ウェブサイトが共有データの受信先として登録されるケースの標準化が試みられています。詳細は Web Share Target を参照してください。

場合によっては、ホストOSがWeb Shareに類似した共有やインテントシステムを提供することがあります。その場合、ユーザーエージェントは共有データをOSに転送するだけで、ネイティブアプリへ直接送信する必要はありません。

4. Permissions Policy との統合

この仕様は、文字列 "web-share" によって識別されるポリシー制御パーミッションを定義します。 その デフォルト許可リスト'self' です。つまり、サードパーティコンテキストではデフォルトでAPIの利用が 許可されません

ユーザーエージェントが Permissions PolicyPermissions-Policy HTTPヘッダーをサポートするかどうかは 任意 です。

開発者は、Permissions Policy 仕様で定義された手段を使って、サードパーティコンテキストがこのAPIを 利用可能かどうかを制御できます。

注記: Permissions Policy 実装状況

5. アクセシビリティに関する考慮事項

このセクションは規範的ではありません。

この仕様を使ってユーザーインターフェースで情報を表示する場合、実装者はプラットフォームのOSレベルのアクセシビリティガイドラインに従うことが望まれます。また、共有はエンドユーザーに対してセキュリティ上の影響を及ぼす可能性があるため、share() メソッドの説明にあるように、共有UIはアクセシブルかつプラットフォームのセキュリティガイドラインも考慮して設計する必要があります。主な考慮点は以下の通りです:

これらの要素は、視覚・運動・認知障害を持つユーザーがウェブページで共有されるコンテンツの性質をより理解できるようにします。

6. プライバシーに関する考慮事項

7. 適合性

非規範的と明記されたセクション以外にも、この仕様書中の著作ガイドライン、図、例、注記はすべて非規範的です。それ以外の内容はすべて規範的です。

本書の MAYMUSTOPTIONALSHOULD というキーワードは、 BCP 14 [RFC2119] [RFC8174] に記載された通り、ここに示すようにすべて大文字で現れる場合に限り、その意味で解釈されます。

8. IDL索引

WebIDLpartial interface Navigator {
  [SecureContext] Promise<undefined> share(optional ShareData data = {});
  [SecureContext] boolean canShare(optional ShareData data = {});
};

dictionary ShareData {
  sequence<File> files;
  USVString title;
  USVString text;
  USVString url;
};

9. 変更履歴

このセクションは規範的ではありません。

勧告案フェーズで、仕様に以下の規範的変更が加えられました。完全な変更リストはコミットログをご覧ください。

最初の公開ワーキングドラフトから勧告候補までに仕様に加えられた規範的変更は以下の通りです。完全な変更リストはコミットログをご覧ください。

A. 謝辞

編集者は、下記の W3C グループの貴重なフィードバックに感謝します。これにより本仕様は大きく改善されました: Accessible Platform Architectures Working GroupInternationalization Working GroupPrivacy Interest GroupTechnical Architecture Group

Web Intents チームにも感謝します。彼らはウェブアプリの相互運用ユースケースの基礎を築きました。特に Paul Kinlan 氏はWeb Shareの初期の普及活動に大きく貢献しました。

B. 参考文献

B.1 規範的参考文献

[fetch]
Fetch標準. Anne van Kesteren. WHATWG. 現行標準. URL: https://fetch.spec.whatwg.org/
[fileapi]
File API. Marijn Kruisselbrink. W3C. 2023年2月6日. W3C作業草案. URL: https://www.w3.org/TR/FileAPI/
[html]
HTML標準. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. 現行標準. URL: https://html.spec.whatwg.org/multipage/
[PERMISSIONS-POLICY]
Permissions Policy. Ian Clelland. W3C. 2023年3月22日. W3C作業草案. URL: https://www.w3.org/TR/permissions-policy-1/
[RFC2119]
RFCで要件レベルを示すためのキーワード. S. Bradner. IETF. 1997年3月. 現行のベストプラクティス. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
RFC 2119キーワードの大文字・小文字の曖昧さ. B. Leiba. IETF. 2017年5月. 現行のベストプラクティス. URL: https://www.rfc-editor.org/rfc/rfc8174
[url]
URL標準. Anne van Kesteren. WHATWG. 現行標準. URL: https://url.spec.whatwg.org/
[WEBIDL]
Web IDL標準. Edgar Chen; Timothy Gu. WHATWG. 現行標準. URL: https://webidl.spec.whatwg.org/

B.2 参考情報

[encoding]
Encoding標準. Anne van Kesteren. WHATWG. 現行標準. URL: https://encoding.spec.whatwg.org/