相关文章推荐
打篮球的冰棍  ·  机器学习 课件 ppt ...·  11 月前    · 
健身的脸盆  ·  binary 和 varbinary ...·  1 年前    · 

在应用之间共享内容在移动设备上很流行,在这些设备上,操作文件或复制内容不如桌面操作系统直观。 例如,在移动设备上,通常通过发送短信与朋友共享图像。 但共享内容不保留给移动设备:还可以在 Windows 上的应用之间共享。

共享内容有两个方向,渐进式 Web 应用 (PWA) 可以处理这两个方向:

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 上,上述代码将触发共享对话框,允许用户选择应用来接收共享内容。 共享对话框如下所示:

函数 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

  • 在“地址”栏的右侧,单击“ 可用应用”。安装 (PWA“应用可用,安装”图标) 按钮将 PWAmp 安装为 PWA。

  • 在已安装的 PWAmp PWA 中,将本地音频文件 (拖动到应用窗口) 。 例如,如果克隆了 MicrosoftEdge/Demos 存储库,则 (Demos 存储库 > pwamp/songs 目录) 具有文件的本地副本.mp3,例如 C:\Users\username\GitHub\Demos\pwamp\songs

  • 在新导入的歌曲旁边,单击“ 歌曲操作 (...) ”按钮,然后选择“ 共享”。 将显示“Windows 共享 ”对话框:

    接收共享内容

    通过使用 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 请求。 共享数据作为 titletexturl 查询参数传递。 发出以下请求: /handle-shared-content/?title=shared title&text=shared text&url=shared url

    如果现有代码使用其他查询参数名称,则可以将默认 titletexturl 查询参数映射到其他名称。 在以下示例中 title, 、 texturl 查询参数映射到 subjectbodyaddress

    "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);
            })());
                  通过 Web 共享 API 与 OS 共享 UI 集成
  • 使用 Web 共享目标 API 接收共享数据
  •