利用 Web Share Target API 简化了移动设备和桌面设备上的分享功能
在移动设备或桌面设备上,分享应该非常简单,只需点击分享按钮、选择应用,然后选择要与谁分享即可。例如,您可以通过通过电子邮件将其发送给朋友或将其发布在 Twitter 微博中来分享有趣的文章。
过去,只有平台专用应用才能向操作系统注册,以便从其他安装式应用接收共享。不过,借助 Web Share Target API,已安装的 Web 应用可以作为分享目标向底层操作系统注册,以接收分享的内容。
了解 Web Share Target 的实际运用
- 使用 Android 版 Chrome 76 或更高版本,或桌面版 Chrome 89 或更高版本,打开“网页分享目标”演示。
- 出现提示时,点击安装将应用添加到主屏幕,或使用 Chrome 菜单将其添加到主屏幕。
- 打开任何支持分享的应用,或使用演示版应用中的“分享”按钮。
- 从目标选择器中,选择网站分享测试。
共享后,您应该会在网络共享目标 Web 应用中看到所有共享的信息。
将您的应用注册为共享目标
如需将应用注册为分享目标,该应用需要满足 Chrome 的可安装性条件。此外,用户必须先将您的应用添加到主屏幕,然后才能向其分享内容。这可防止网站随机将自己添加到用户的分享 intent 选择器中,并确保用户希望通过您的应用执行分享操作。
更新您的 Web 应用清单
如需将应用注册为分享目标,请将 share_target
条目添加到其网站应用清单中。这会指示操作系统在 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'));
});
请务必使用服务工作器预缓存 action
网页,以便其快速加载并可靠运行,即使用户处于离线状态也是如此。Workbox 是一款可帮助您在服务工作器中实现预缓存的工具。
处理 POST 分享
如果您的 method
为 "POST"
(例如,目标应用接受已保存的书签或共享文件),则传入 POST
请求的正文包含共享应用传递的数据,这些数据使用清单中提供的 enctype
值进行编码。
前台页面无法直接处理此类数据。由于页面将数据视为请求,因此会将其传递给服务工作器,您可以在服务工作器中使用 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,如下所述:
在所有平台上,您的网站应用都必须先安装,然后才会显示为接收共享数据的潜在目标。
示例应用
显示对该 API 的支持
您打算使用 Web Share Target API 吗?您的公开支持有助于 Chromium 团队确定功能的优先级,并向其他浏览器供应商表明支持这些功能的重要性。
使用 #WebShareTarget
标签向 @ChromiumDev 发送推文,告诉我们您在哪里以及如何使用该工具。