应用间共享数据
应用程序共享是指一个应用程序能够将信息或数据传递到同一设备上的另一个应用程序的功能。此功能对用户很有用,因为它允许他们在两个应用程序之间共享信息,而无需这些应用程序事先了解彼此。
例如,在您的移动设备上,您可以将照片或视频从您的照片应用程序共享到另一个接受图像的应用程序,例如电子邮件应用程序。此共享模式由安装这两个应用程序的操作系统 (OS) 协调。
- 当用户启动照片共享时,照片应用程序会准备所选图像的数据,并将其交给操作系统。
- 操作系统会选择能够处理共享图像数据的应用程序列表,并将其显示给用户。
- 用户选择其中一个目标应用程序后,操作系统会启动该应用程序并将其与共享的图像一起启动。
渐进式 Web 应用 (PWA) 也能够使用相同的操作系统协调模式共享信息。PWA 可以共享数据,也可以接受共享数据。
在构建 PWA 时,接受共享数据可以使您的 PWA 感觉更熟悉,并自然地集成到用户的设备中。
与其他应用共享数据
要使用户能够从您的 PWA 与其他应用共享数据,请使用 Web 共享 API。Web 共享 API 允许您的应用通过底层操作系统的共享机制与其他应用共享文本、链接或文件。
要共享数据,请在响应用户操作(例如按钮点击)时使用 navigator.share()
方法。
检查支持情况
在应用程序中显示内容共享 UI 之前,请确保支持 Web 共享 API 功能。即使支持 Web 共享 API 的浏览器也不都支持共享所有类型的数据。因此,最好先使用 navigator.canShare()
方法来验证您要共享的数据是否确实可以从运行您的应用程序的浏览器中共享。
此示例演示如何检查是否支持 Web 共享 API 以及数据是否可以共享。
function canBrowserShareData(data) {
if (!navigator.share || !navigator.canShare) {
return false;
}
return navigator.canShare(data);
}
const sharedDataSample = {
title: "Some text title",
text: "More text",
url: "A url we want to share",
};
if (canBrowserShareData(sharedDataSample)) {
// Enable the share button in the UI.
renderAppSharingUI();
} else {
// We can't share on this browser/operating system.
}
处理异常
navigator.share()
方法返回一个 Promise
,在某些情况下可能会被拒绝,例如共享数据不正确、用户中止共享操作或数据传输失败时。
因此,务必捕获 promise 拒绝,以避免应用程序的 JavaScript 代码中出现错误。
async function shareData(data) {
try {
await navigator.share(data);
// The data was shared successfully.
} catch (e) {
// The data could not be shared.
console.error(`Error: ${e}`);
}
}
共享文本数据
以下示例演示如何在应用程序中的按钮被点击时共享链接和一些文本。示例中使用的 canBrowserShareData
函数在 检查支持情况 中进行了描述,此处不再重复。
// Retrieve the button from the DOM. The button is hidden for now.
const button = document.querySelector("#share");
if (canBrowserShareData({ text: "text", url: "https://example.com" })) {
// Show the button.
button.style.display = "inline";
// Listen for click events on the button to share data.
button.addEventListener("click", async () => {
try {
await navigator.share({
text: "An MDN article to learn how to share data between apps",
url: "https://mdn.org.cn/docs/Web/Progressive_web_apps/How_to/Share_data_between_apps",
});
console.log("The URL was successfully shared");
} catch (err) {
console.error(`The URL could not be shared: ${err}`);
}
});
}
共享文件
以下代码示例演示如何在应用程序中的按钮被点击时共享文件。canBrowserShareFiles
函数用于仅在浏览器支持共享文件时显示共享按钮。
function canBrowserShareFiles() {
if (!navigator.share || !navigator.canShare) {
return false;
}
// Create some test data with a file, to check if the browser supports
// sharing it.
const testFile = new File(["foo"], "foo.txt", { type: "text/plain" });
const data = { files: [testFile] };
return navigator.canShare(data);
}
// Retrieve the button from the DOM. The button is hidden for now.
const button = document.querySelector("#share");
if (canBrowserShareFiles()) {
// The browser supports sharing files. Show the button.
button.style.display = "inline";
// Listen for clicks on the button and share a file.
button.addEventListener("click", async () => {
try {
// Get the file to be shared. This function should return a File
// object, perhaps by creating it dynamically, or retrieving it
// from IndexedDB.
const file = await getTheFileToShare();
await navigator.share({
title: "My shared file",
files: [file],
});
console.log("The file was successfully shared");
} catch (err) {
console.error(`The file could not be shared: ${err}`);
}
});
}
有关更多信息,请参阅 navigator.share()
方法页面上的共享文件示例。
处理来自其他应用的共享数据
要将您的 PWA 注册为其他应用程序共享数据的目标,请使用 Web 共享目标 API,尤其是 share_target
Web 应用清单成员。
share_target
清单成员允许已安装的 PWA 在操作系统级别注册为其他应用程序共享内容的潜在目标。这意味着,当用户从另一个应用程序共享与您的 PWA 兼容的一些数据时,操作系统将与其他典型的共享目标(如电子邮件或消息应用程序)一起列出您的 PWA。请注意,PWA 必须已安装才能显示为接收共享数据的潜在目标。
您在清单文件中使用 share_target
成员提供的信息定义了您的应用程序可以成为哪些数据的目标,以及当用户将其选为目标时,操作系统应如何启动您的应用程序。
处理文本数据
这是一个使用 share_target
成员的 Web 应用清单示例。
{
"name": "ChattyBox",
"start_url": "/",
"display": "standalone",
"icons": [
{
"src": "images/icon-256.png",
"sizes": "256x256",
"type": "image/png"
}
],
"share_target": {
"action": "/share-handler",
"method": "GET",
"params": {
"text": "description",
"url": "link"
}
}
}
当用户选择您的应用程序来处理另一个应用程序的共享内容时,您的应用程序将启动,并且共享内容将以类似于 <form>
元素提交的方式传递给它。
在前面的 Web 应用清单代码示例中,当选择 ChattyBox 应用程序作为目标时,它会通过在 /share-handler
URL 上发出 HTTP GET
请求来启动,并将共享数据作为名为 description
和 link
的请求参数传递。
GET
请求将如下所示:/shared-handler?description=...&link=...
。
然后,您的应用程序的主 JavaScript 代码可以使用 URLSearchParams 接口检索共享数据。
const url = new URL(document.location);
const sharedDescription = url.searchParams.get("description");
const sharedLink = url.searchParams.get("link");
有关更多信息,请参阅 share_target
Web 应用清单成员页面上的示例 使用 GET 接收共享数据。
处理共享文件
在前面的示例中,文本数据作为 GET
请求处理。但是,处理文件需要使用具有 multipart/form-data
编码类型 的 POST
请求。
以下代码片段显示了如何配置 PWA 以接受不同类型的共享文件。
{
"name": "ChattyBox",
"start_url": "/",
"display": "standalone",
"icons": [
{
"src": "images/icon-256.png",
"sizes": "256x256",
"type": "image/png"
}
],
"share_target": {
"action": "/share-file-handler",
"method": "POST",
"enctype": "multipart/form-data",
"params": {
"files": [
{
"name": "textFiles",
"accept": ["text/plain", ".txt"]
},
{
"name": "htmlFiles",
"accept": ["text/html", ".html"]
},
{
"name": "images",
"accept": ["image/jpeg", "image/png", "image/webp", "image/gif"]
}
]
}
}
}
如本示例所示,files
属性中的每个文件对象都必须具有 name
属性和 accept
属性。accept
属性必须指定可接受的 MIME 类型 或文件扩展名。
当用户选择应用程序来处理共享文件(或文件)时,应用程序将使用 POST
请求在 /share-file-handler
URL 上启动,并带有编码的表单数据。
因为这是一个 POST
请求,所以您的应用程序的主 JavaScript 代码无法直接访问表单数据。您可以通过在服务器端代码中接收它们(在 /share-file-handler
URL 终结点处)来处理提交的文件。但是,为了获得更好的脱机用户体验,您可以使用 fetch
事件处理程序 在服务工作线程代码中处理这些文件,如下所示。
// service-worker.js
self.addEventListener("fetch", (event) => {
// Only use this event listener for POST requests sent to /share-file-handler.
const url = new URL(event.request.url);
if (
event.request.method !== "POST" ||
url.pathname !== "/share-file-handler"
) {
return;
}
event.respondWith(
(async () => {
// Get the data from the submitted form.
const formData = await event.request.formData();
// Get the submitted files.
const textFiles = formData.getAll("textFiles");
const htmlFiles = formData.getAll("htmlFiles");
const imageFiles = formData.getAll("images");
// Send the files to the frontend app.
sendFilesToFrontend(textFiles, htmlFiles, imageFiles);
// Redirect the user to a URL that shows the imported files.
return Response.redirect("/display-new-files", 303);
})(),
);
});
在此代码示例中,共享文件是从表单数据中提取的,并且用户被重定向到另一个页面。您可以使用服务工作线程中的代码根据需要处理提取的文件。例如,您可以使用 Worker.postMessage()
方法将它们发送到应用程序的主 JavaScript 代码,或者将它们存储在可由服务工作线程和应用程序的主 JavaScript 代码访问的 Indexed DB 数据库中。
有关更多信息,请参阅 share_target
Web 应用清单成员页面上的 接收共享文件 示例。
另请参阅
- Web 共享 API
share_target
清单成员- 使用 Web 共享 API 集成到操作系统共享 UI 中 on web.dev
- 使用 Web 共享目标 API 接收共享数据 on developer.chrome.com
- 与其他应用共享内容 on microsoft.com