【问题标题】:How to copy web notification content to clipboard如何将网络通知内容复制到剪贴板
【发布时间】:2020-09-03 20:30:55
【问题描述】:

我正在使用 Firebase 云消息传递 (FCM) 发送数据消息,以便我可以使用 Service Worker 处理通知。现在我使用 Service Worker 显示通知,当我单击通知时,我想将通知的内容复制到剪贴板中。

const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler((payload)=> {
    const title = payload.data.title;
    const options = {
        body: payload.data.body
    };
    return self.registration.showNotification(title,
        options);
});

self.addEventListener('notificationclick', (event)=>{
    console.log(event);
    navigator.clipboard.writeText(event).then(function() {
        console.log('Async: Copying to clipboard was successful!');
      }, function(err) {
        console.error('Async: Could not copy text: ', err);
      });
});

当点击通知时notificationclick 事件被触发。但我得到navigator.clipboard 未定义。我也在为我的网站使用安全域。我也无法使用document.execcommand('copy'),因为使用 Service Worker 无法访问 DOM。您能否建议一种无需打开任何网址即可复制通知内容的方法?

【问题讨论】:

  • 我认为你需要这个:developer.mozilla.org/en-US/docs/Web/API/Client/postMessage 你将能够在客户端做你想做的事。让我知道如果它对你有帮助,我会做一个anwser
  • 似乎您必须打开一个实际的浏览器窗口才能运行复制命令,否则您无权访问该 API。也许打开它、复制和关闭它可能就像从未发生过一样发生?即使知道它并不理想,我也会尝试了解它的进展情况。
  • @Gilsdav as postMessage 仅适用于 DOM,但我不想打开任何窗口。
  • @enapupe 是的,navigator.cilpborad 将不起作用。但我正在寻找其他方法来实现相同的目标。

标签: javascript service-worker web-notifications


【解决方案1】:

您不能从 ServiceWorker 复制到剪贴板。您需要一个活动的前台浏览器选项卡/窗口才能复制到剪贴板。

来自 chrome 网络更新存档 https://developers.google.com/web/updates/2018/03/clipboardapi

与许多新 API 一样,navigator.clipboard 仅支持通过 HTTPS 提供的页面。 为帮助防止滥用,只有当页面是活动标签时才允许访问剪贴板。活动选项卡中的页面无需请求权限即可写入剪贴板,但从剪贴板读取始终需要权限。

我还检查了 ServiceWorkers 和剪贴板 API 的浏览器规范,没有一个定义任何关于服务工作者上下文的特定内容。

编辑:我已经就这个特定问题联系了该帖子的作者https://mobile.twitter.com/_developit/status/1264290519926128641

我不相信它在 service worker 中可用。我的建议是让通知点击处理程序打开一个尚未打开的页面,并在收到事件时在该页面内同步调用 writeText()。

【讨论】:

    【解决方案2】:

    您可以使用客户端postMessage API:

    服务工作者:

    self.addEventListener('notificationclick', (event)=>{
        console.log(event);
    
        if (!event.clientId) return;
        const client = await clients.get(event.clientId);
        if (!client) return;
    
        client.postMessage({
          type: 'clipboard',
          msg: event
        });
    });
    

    简单的脚本:

    navigator.serviceWorker.addEventListener('message', event => {
      if(event.data.type === 'clipboard') {
          navigator.clipboard.writeText(event.data.msg).then(function() {
            console.log('Async: Copying to clipboard was successful!');
          }, function(err) {
            console.error('Async: Could not copy text: ', err);
          });
      }
    });
    
    

    请记住,Safari 不支持此功能。

    【讨论】:

    • 如前所述,我不想打开页面。那么我们要如何执行 Simple 脚本呢?
    • 我认为您可以打开一个仅复制到clipbloard clients.openWindow 的窗口,然后直接关闭。 developer.mozilla.org/en-US/docs/Web/API/Clients
    猜你喜欢
    • 1970-01-01
    • 2017-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多