与其他应用共享内容
在应用之间共享内容在移动设备上很流行,在这些设备上,操作文件或复制内容不如桌面操作系统直观。 例如,在移动设备上,通常通过发送短信与朋友共享图像。 但共享内容不保留给移动设备:还可以在 Windows 上的应用之间共享。
共享内容有两个方向,渐进式 Web 应用 (PWA) 可以处理这两个方向:
方向 | 说明 |
---|---|
共享内容 | 若要共享内容,PWA 会) 生成内容 ((如文本、链接或文件),并将共享内容移交给操作系统。 操作系统允许用户决定要使用哪个应用来接收该内容。 |
接收共享内容 | 若要接收内容,PWA 充当内容目标。 PWA 作为内容共享目标注册到操作系统。 |
注册为共享目标的 PWA 感觉本机集成到 OS 中,并且对用户更具吸引力。
共享内容
PWA 可以使用 Web 共享 API 触发显示操作系统共享对话框。
注意
Web 共享仅适用于通过 HTTPS 服务的网站, (这是 PWA) 的情况,并且只能在响应用户操作时调用。
若要共享链接、文本或文件等内容,请使用 navigator.share
函数,如下所示。 函数 navigator.share
接受应至少具有以下属性之一的对象:
-
title
:共享内容的简短标题。 -
text
:共享内容的较长说明。 -
url
:要共享的资源的地址。 -
files
:要共享的文件数组。
function shareSomeContent(title, text, url) {
if (!navigator.share) {
return;
}
navigator.share({title, text, url}).then(() => {
console.log('The content was shared successfully');
}).catch(error => {
console.error('Error sharing the content', error);
});
}
在上面的代码中,我们首先通过测试 是否 navigator.share
定义了 来检查浏览器是否支持 Web 共享。 该 navigator.share
函数返回一个 Promise 对象,该对象在共享成功时解析,并在发生错误时拒绝。
由于此处使用了 Promise,因此可将上述代码重写为函数 async
,如下所示:
async function shareSomeContent(title, text, url) {
if (!navigator.share) {
return;
}
try {
await navigator.share({title, text, url});
console.log('The content was shared successfully');
} catch (e) {
console.error('Error sharing the content', e);
}
}
在 Windows 上,上述代码将触发共享对话框,允许用户选择应用来接收共享内容。 共享对话框如下所示:
用户选择应用接收共享内容后,由此应用以任何方式处理它。 例如,电子邮件应用可能会使用 title
作为电子邮件主题,并使用 text
作为电子邮件正文。
共享文件
函数 navigator.share
还接受数组 files
以与其他应用共享文件。
在共享文件之前,请务必测试浏览器是否支持共享文件。 若要检查是否支持共享文件,请使用 navigator.canShare
函数:
function shareSomeFiles(files) {
if (navigator.canShare && navigator.canShare({files})) {
console.log('Sharing files is supported');
} else {
console.error('Sharing files is not supported');
}
}
共享 files
对象成员必须是对象的数组 File
。 详细了解 文件接口。
构造 File
对象的一种方法是:
- 首先,使用
fetch
API 请求资源。 - 然后,使用返回的响应创建新的
File
。
此方法如下所示。
async function getImageFileFromURL(imageURL, title) {
const response = await fetch(imageURL);
const blob = await response.blob();
return new File([blob], title, {type: blob.type});
}
在上面的代码中:
- 函数
getImageFileFromURL
使用 URL 提取图像。 - 函数
response.blob()
将图像转换为 BLOB) (二进制大型对象。 - 代码使用 BLOB 创建
File
对象。
共享内容的演示
PWAmp 是一个演示 PWA,它使用 navigator.share
函数共享文本和链接。
若要测试“共享”功能,请执行以下操作:
转到 PWAmp。
在“地址”栏的右侧,单击“ 可用应用”。安装 () 按钮将 PWAmp 安装为 PWA。
在已安装的 PWAmp PWA 中,将本地音频文件 (拖动到应用窗口) 。 例如,如果克隆了 MicrosoftEdge/Demos 存储库,则 (Demos 存储库 > pwamp/songs 目录) 具有文件的本地副本
.mp3
,例如C:\Users\username\GitHub\Demos\pwamp\songs
。在新导入的歌曲旁边,单击“ 歌曲操作 (...) ”按钮,然后选择“ 共享”。 将显示“Windows 共享 ”对话框:
选择要在其中共享内容的应用。
可以在 GitHub 上找到 PWAmp 源代码 。 PWAmp 应用使用 app.js 源文件中的 Web 共享 API。
接收共享内容
通过使用 Web 共享目标 API,PWA 可以注册为在系统共享对话框中显示为应用。 然后,PWA 可以使用 Web 共享目标 API 来处理来自其他应用的共享内容。
注意
只有已安装的 PWA 才能注册为共享目标。
注册为目标
若要接收共享内容,首先要做的是将 PWA 注册为共享目标。 若要注册,请使用 share_target
清单成员。 安装应用后,操作系统将使用 成员 share_target
将应用包含在系统共享对话框中。 操作系统知道在用户选取应用时要执行哪些操作来共享内容。
成员 share_target
必须包含系统向应用传递共享内容所需的信息。 请考虑以下清单代码:
{
"share_target": {
"action": "/handle-shared-content/",
"method": "GET",
"params": {
"title": "title",
"text": "text",
"url": "url",
}
}
}
当用户选择应用作为共享内容的目标时,将启动 PWA。 对 GET
属性指定的 action
URL 发出 HTTP 请求。 共享数据作为 title
、 text
和 url
查询参数传递。 发出以下请求: /handle-shared-content/?title=shared title&text=shared text&url=shared url
。
如果现有代码使用其他查询参数名称,则可以将默认 title
、 text
和 url
查询参数映射到其他名称。 在以下示例中 title
, 、 text
和 url
查询参数映射到 subject
、 body
和 address
:
{
"share_target": {
"action": "/handle-shared-content/",
"method": "GET",
"params": {
"title": "subject",
"text": "body",
"url": "address",
}
}
}
处理 GET 共享数据
若要处理 PWA 代码中通过 GET 请求共享的数据,请使用 URL
构造函数提取查询参数:
window.addEventListener('DOMContentLoaded', () => {
console url = new URL(window.location);
const sharedTitle = url.searchParams.get('title');
const sharedText = url.searchParams.get('text');
const sharedUrl = url.searchParams.get('url');
});
处理 POST 共享数据
如果共享数据旨在以任何方式更改应用(例如通过更新存储在应用中的某些内容),则必须使用 POST
方法并使用 定义编码类型 enctype
:
{
"share_target": {
"action": "/post-shared-content",
"method": "POST",
"enctype": "multipart/form-data",
"params": {
"title": "title",
"text": "text",
"url": "url",
}
}
}
POST
HTTP 请求包含编码为 的multipart/form-data
共享数据。 可以使用服务器端代码访问 HTTP 服务器上的此数据,但当用户脱机时,此方法不起作用。 若要提供更好的体验,请使用服务辅助角色,并使用 fetch
事件侦听器访问服务辅助角色中的数据,如下所示:
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
if (event.request.method === 'POST' && url.pathname === '/post-shared-content') {
event.respondWith((async () => {
const data = await event.request.formData();
const title = data.get('title');
const text = data.get('text');
const url = data.get('url');
// Do something with the shared data here.
return Response.redirect('/content-shared-success', 303);
})());
}
});
在上面的代码中:
服务辅助角色截获请求
POST
。以某种方式使用数据 ((例如)将内容存储在本地) 。
将用户重定向到成功页面。 这样,即使网络关闭,应用也能正常工作。 应用可以选择仅在本地存储内容,也可以在以后 (使用 后台同步) 等方式还原连接时将内容发送到服务器。
处理共享文件
应用还可以处理共享文件。 若要处理 PWA 中的文件,必须使用 POST
方法和 multipart/form-data
编码类型。 此外,必须声明应用可以处理的文件类型。
{
"share_target": {
"action": "/store-code-snippet",
"method": "POST",
"enctype": "multipart/form-data",
"params": {
"title": "title",
"files": [
{
"name": "textFile",
"accept": ["text/plain", "text/html", "text/css",
"text/javascript"]
}
]
}
}
}
上述清单代码告知系统,你的应用可以接受具有各种 MIME 类型的文本文件。 文件扩展名(如 .txt
)也可在数组中 accept
传递。
若要访问共享文件,请使用 formData
之前的请求,并使用 FileReader
来读取内容,如下所示:
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
if (event.request.method === 'POST' && url.pathname === '/store-code-snippet') {
event.respondWith((async () => {
const data = await event.request.formData();
const filename = data.get('title');
const file = data.get('textFile');
const reader = new FileReader();
reader.onload = function(e) {
const textContent = e.target.result;
// Do something with the textContent here.
};
reader.readAsText(file);
return Response.redirect('/snippet-stored-success', 303);
})());
}
});