使用 Web Share Target API 轻松在移动设备和桌面设备上进行分享
在移动设备或桌面设备上,分享操作应该简单到只需点击分享按钮、选择应用并选择分享对象即可。例如,您可能希望通过电子邮件将一篇有趣的文章发送给朋友,或者将其发布到 Twitter 上,分享给全世界。
过去,只有平台专用应用可以向操作系统注册以从其他已安装的应用接收共享内容。但是,使用 Web Share Target API,已安装的 Web 应用可以向底层操作系统注册为共享目标,以接收分享内容。
了解网络分享目标的实际效果
- 在桌面设备上使用 Chrome 76 或更高版本(Android 版)或 Chrome 89 或更高版本,打开网络共享目标演示。
- 出现提示时,点击安装将应用添加到主屏幕,或使用 Chrome 菜单将其添加到主屏幕。
- 打开任何支持分享的应用,或使用演示版应用中的“分享”按钮。
- 从目标选择器中,选择 Web Share Test。
分享后,您应该会在 Web 共享目标 Web 应用中看到所有共享的信息。
将您的应用注册为共享目标
如需将应用注册为共享目标,该应用必须符合 Chrome 的可安装性标准。此外,用户必须先将其添加到自己的主屏幕,然后才能与您的应用分享。这样可以防止网站随机将自己添加到用户的分享 intent 选择器,并确保用户希望通过您的应用进行分享。
更新 Web 应用清单
如需将应用注册为共享目标,请将 share_target
条目添加到其 Web 应用清单中。它会指示操作系统将您的应用作为一个选项添加到 intent 选择器中。您添加到清单中的内容控制着您的应用接受的数据。share_target
条目有三种常见场景:
- 接受基本信息
- 正在接受应用更改
- 正在接受文件
接受基本信息
如果您的目标应用仅接受基本信息(如数据、链接和文本),请将以下代码添加到 manifest.json
文件中:
"share_target": {
"action": "/share-target/",
"method": "GET",
"params": {
"title": "title",
"text": "text",
"url": "url"
}
}
如果您的应用已有共享网址方案,您可以将 params
值替换为现有的查询参数。例如,如果您的共享网址架构使用 body
而不是 text
,您可以将 "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
字段。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
以查找网址,并将其添加为链接。 - 照片分享应用可以使用
title
作为幻灯片标题,使用text
作为说明,使用files
作为幻灯片演示图片来创建新的幻灯片。 - 短信应用可以将
text
和url
串联在一起并丢弃title
来起草新消息。
正在处理 GET 分享次数
如果用户选择您的应用,并且您的 method
为 "GET"
(默认值),浏览器会使用 action
网址打开一个新窗口。然后,浏览器会使用清单中提供的网址编码值生成查询字符串。例如,如果分享应用提供 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 上,url
字段将为空,因为 Android 的共享系统不支持该字段。网址会经常出现在 text
字段中,偶尔也会出现在 title
字段中。
浏览器支持
Web Share Target API 受支持,如下所述:
在所有平台上,都必须先安装 Web 应用,它才会显示为接收共享数据的潜在目标。
示例应用
显示对该 API 的支持
您打算使用 Web Share Target API 吗?您的公开支持有助于 Chromium 团队确定功能的优先级,并向其他浏览器供应商表明支持这些功能的重要性。
请使用 # 标签 #WebShareTarget
向 @ChromiumDev 发送一条推文,并告诉我们您使用该产品的位置和方式。