Web Share Target API によるモバイルとパソコンでの共有の簡素化
モバイル デバイスまたはパソコンでは、[共有] ボタンをクリックしてアプリを選択し、共有相手を選択するだけで簡単に共有できます。たとえば、興味深い記事を友人にメールで送信したり、世界中にツイートしたりして共有することができます。
これまでは、インストールされている他のアプリからの共有を受け取るためにオペレーティング システムに登録できるのは、プラットフォーム固有のアプリのみでした。ただし、Web Share Target API を使用すると、インストール済みのウェブアプリを共有ターゲットとして基盤となるオペレーティング システムに登録し、共有コンテンツを受信できます。
ウェブ共有ターゲットの使用例
- Android 版 Chrome 76 以降、またはパソコン版 Chrome 89 以降を使用して、ウェブ共有ターゲット デモを開きます。
- メッセージが表示されたら、[インストール] をクリックしてアプリをホーム画面に追加するか、Chrome メニューを使用してホーム画面に追加します。
- 共有をサポートするアプリを開くか、デモアプリの共有ボタンを使用します。
- ターゲット選択ツールで [Web Share Test] を選択します。
共有後、ウェブ共有ターゲット ウェブアプリに共有情報がすべて表示されます。
アプリを共有ターゲットとして登録する
アプリを共有先として登録するには、Chrome のインストール可能条件を満たしている必要があります。また、ユーザーがアプリを共有するには、ホーム画面にアプリを追加する必要があります。これにより、サイトがユーザーの共有インテント選択ツールにランダムに追加されることを防ぎ、ユーザーがアプリで共有することを望んでいることを確認できます。
ウェブアプリ マニフェストを更新する
アプリを共有先として登録するには、ウェブアプリ マニフェストに share_target
エントリを追加します。これにより、アプリをインテント選択ツールのオプションとして含めるようオペレーティング システムに指示します。マニフェストに追加する内容によって、アプリが受け入れるデータが決まります。share_target
エントリの一般的なシナリオは次の 3 つです。
- 基本情報の受け取り
- 申請の変更の承認
- ファイルの受信
基本情報を受け入れる
ターゲット アプリがデータ、リンク、テキストなどの基本情報のみを受け入れる場合、manifest.json
ファイルに以下を追加します。
"share_target": {
"action": "/share-target/",
"method": "GET",
"params": {
"title": "title",
"text": "text",
"url": "url"
}
}
アプリに共有 URL スキームがすでにある場合は、params
値を既存のクエリ パラメータに置き換えることができます。たとえば、共有 URL スキームで text
ではなく body
を使用している場合は、"text": "text"
を "text":
"body"
に置き換えることができます。
method
値が指定されていない場合、デフォルトは "GET"
です。この例に示されていない enctype
フィールドは、データのエンコードのタイプを示します。"GET"
メソッドの場合、enctype
はデフォルトで "application/x-www-form-urlencoded"
に設定され、それ以外に設定されている場合は無視されます。
申請の変更の承認
共有データによってターゲット アプリになんらかの変更(ターゲット アプリにブックマークを保存するなど)がある場合は、method
値を "POST"
に設定し、enctype
フィールドを含めます。次の例では、ターゲット アプリにブックマークを作成するため、method
には "POST"
、enctype
には "multipart/form-data"
を使用しています。
{
"name": "Bookmark",
"share_target": {
"action": "/bookmark",
"method": "POST",
"enctype": "multipart/form-data",
"params": {
"url": "link"
}
}
}
ファイルの受信
アプリケーションの変更と同様に、ファイルを受け入れるには、method
が "POST"
であり、enctype
が存在している必要があります。また、enctype
は "multipart/form-data"
にする必要があり、files
エントリを追加する必要があります。
また、アプリが受け入れるファイルの種類を定義する files
配列も追加する必要があります。配列要素は、name
フィールドと accept
フィールドの 2 つのメンバーを持つエントリです。accept
フィールドには、MIME タイプ、ファイル拡張子、またはその両方を含む配列を指定します。オペレーティング システムによって優先されるものが異なるため、MIME タイプとファイル拡張子の両方を含む配列を指定することをおすすめします。
{
"name": "Aggregator",
"share_target": {
"action": "/cgi-bin/aggregate",
"method": "POST",
"enctype": "multipart/form-data",
"params": {
"title": "name",
"text": "description",
"url": "link",
"files": [
{
"name": "records",
"accept": ["text/csv", ".csv"]
},
{
"name": "graphs",
"accept": "image/svg+xml"
}
]
}
}
}
受信コンテンツを処理する
受信した共有データを処理する方法は、アプリによって異なります。たとえば、次のように処理できます。
- メール クライアントは、
title
をメールの件名として使用し、text
とurl
を本文として連結して、新しいメールの下書きを作成できます。 - ソーシャル ネットワーク アプリでは、
title
を無視してtext
をメッセージの本文に、url
をリンクとして追加することで、新しい投稿の下書きを作成できます。text
がない場合、アプリは本文でもurl
を使用することがあります。url
がない場合、アプリはtext
をスキャンして URL を探し、リンクとして追加することがあります。 - フォト共有アプリは、スライドショーのタイトルとして
title
、説明としてtext
、スライドショーの画像としてfiles
を使用して、新しいスライドショーを作成できます。 - テキスト メッセージ アプリは、
text
とurl
を連結してtitle
を削除し、新しいメッセージの下書きを作成できます。
GET 共有の処理
ユーザーがアプリを選択し、method
が "GET"
(デフォルト)の場合、ブラウザは action
URL で新しいウィンドウを開きます。ブラウザは、マニフェストで指定された URL エンコード値を使用してクエリ文字列を生成します。たとえば、共有アプリが title
と text
を提供している場合、クエリ文字列は ?title=hello&text=world
です。これを処理するには、フォアグラウンド ページで DOMContentLoaded
イベント リスナーを使用して、クエリ文字列を解析します。
window.addEventListener('DOMContentLoaded', () => {
const parsedUrl = new URL(window.location);
// searchParams.get() will properly handle decoding the values.
console.log('Title shared: ' + parsedUrl.searchParams.get('title'));
console.log('Text shared: ' + parsedUrl.searchParams.get('text'));
console.log('URL shared: ' + parsedUrl.searchParams.get('url'));
});
ユーザーがオフラインの場合でも、ページが迅速に読み込まれ、確実に機能するように、Service Worker を使用して action
ページをプリキャッシュしてください。Workbox は、Service Worker に事前キャッシュを実装するのに役立つツールです。
POST 共有の処理
method
が "POST"
の場合(保存したブックマークや共有ファイルをターゲット アプリが受け入れる場合など)、受信した POST
リクエストの本文には、マニフェストで指定された enctype
値を使用してエンコードされた、共有アプリケーションから渡されたデータが含まれます。
フォアグラウンド ページは、このデータを直接処理できません。ページはデータをリクエストと見なすため、ページはデータを Service Worker に渡します。ここで、fetch
イベント リスナーを使用してデータをインターセプトできます。そこから、postMessage()
を使用してデータをフォアグラウンド ページに戻すか、サーバーに渡すことができます。
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
// If this is an incoming POST request for the
// registered "action" URL, respond to it.
if (event.request.method === 'POST' &&
url.pathname === '/bookmark') {
event.respondWith((async () => {
const formData = await event.request.formData();
const link = formData.get('link') || '';
const responseUrl = await saveBookmark(link);
return Response.redirect(responseUrl, 303);
})());
}
});
共有コンテンツの確認
受信データを必ず検証してください。残念ながら、他のアプリが適切なコンテンツを適切なパラメータで共有するとは限りません。
たとえば、Android では、Android の共有システムでサポートされていないため、url
フィールドは空になります。多くの場合、URL は text
フィールドに表示されますが、title
フィールドに表示されることもあります。
ブラウザ サポート
Web Share Target API は、以下のようにサポートされています。
どのプラットフォームでも、共有データを受信する可能性のあるターゲットとしてウェブアプリが表示されるには、そのウェブアプリがインストールされている必要があります。
サンプル アプリケーション
API のサポートを表示する
Web Share Target API を使用する予定ですか?公開サポートは、Chromium チームが機能を優先付けするうえで役立ち、他のブラウザ ベンダーに、その機能のサポートがどれほど重要であるかを示します。
ハッシュタグ #WebShareTarget
を使用して @ChromiumDev にツイートし、どこでどのように使用しているかをお知らせください。