【问题标题】:Chrome 76 Copy Content to Clipboard using navigatorChrome 76 使用导航器将内容复制到剪贴板
【发布时间】:2019-12-08 06:35:15
【问题描述】:

我刚刚更新到 chrome 76 stable 并尝试使用新的剪贴板 API 将一些文本(以及稍后的图像)复制到剪贴板。但是,navigator.clipboard.write(data) 似乎不起作用。这是我的代码:

setInterval(function() {
    console.log("Wriing to clipbard");  
    navigator.permissions.query({ name: 'clipboard-write' }).then(result => {
        if (result.state === 'granted') {
            var data = new Blob(["Text data"], {type : "text/plain"});
            navigator.clipboard.write(data).then(function() {
              console.log("Copied to clipboard successfully!");
            }, function(error) {
              console.error("unable to write to clipboard. Error:");
              console.log(error);
            });
        } else {
            console.log("clipboard-permissoin not granted: " + result);
        }
    });
}, 3000);

我在 chrome 扩展内容脚本中运行它,并设置了剪贴板权限,因此权限确实被授予。抛出的错误是:

unable to write to clipboard. Error:

TypeError: Failed to execute 'write' on 'Clipboard': Iterator getter is not callable.

奇怪的是,当我使用navigator.clipboard.write text(text) 而不是navigator.clipboard.write(data) 时,一切正常。问题是,我想使用write(data),因为稍后我也想将图像写入剪贴板。任何想法为什么它不起作用?谢谢。

编辑:我从规格表 https://w3c.github.io/clipboard-apis/#dom-clipboard-write 获得代码

更新:好的,我使用 ClipboardItem 进行文本复制(请参阅下面的答案),但如果我对 dataURL 编码的图像执行相同操作,则整个网页会因“Aw snap”消息而崩溃。所以不确定那里发生了什么。以下是会使网站崩溃并强制重新加载的代码:

setInterval(function() {
    console.log("Wriing to clipbard");  
    navigator.permissions.query({ name: 'clipboard-write' }).then(result => {
        if (result.state === 'granted') {
            //var blob = new Blob(['hello'], {type: 'text/plain'});
            var data = new Blob(["iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg=="], {type : "image/png"});

            var item = new ClipboardItem({'image/png': data});
            navigator.clipboard.write([item]).then(function() {
              console.log("Copied to clipboard successfully!");
            }, function(error) {
              console.error("unable to write to clipboard. Error:");
              console.log(error);
            });
        } else {
            console.log("clipboard-permissoin not granted: " + result);
        }
    });
}, 3000);

【问题讨论】:

    标签: javascript google-chrome-extension clipboard navigator


    【解决方案1】:

    好的,这是适合我的解决方案。在调用 write() 之前,您必须将 blob 包装在 ClipboardItem 对象中。我通过阅读https://bugs.chromium.org/p/chromium/issues/detail?id=150835,然后在网上搜索“ClipboardItem”,然后找到此代码https://github.com/web-platform-tests/wpt/blob/master/clipboard-apis/async-navigator-clipboard-basics.https.html,偶然发现了解决方案。似乎还没有真正的文档,但是嘿,它有效!

    setInterval(function() {
        console.log("Wriing to clipbard");  
        navigator.permissions.query({ name: 'clipboard-write' }).then(result => {
            if (result.state === 'granted') {
                var blob = new Blob(['hello'], {type: 'text/plain'});
                var item = new ClipboardItem({'text/plain': blob});
                navigator.clipboard.write([item]).then(function() {
                  console.log("Copied to clipboard successfully!");
                }, function(error) {
                  console.error("unable to write to clipboard. Error:");
                  console.log(error);
                });
            } else {
                console.log("clipboard-permissoin not granted: " + result);
            }
        });
    }, 3000);
    

    更新:好的,我还可以复制图像(查看相同的来源)。 url 是图片的 url (duh)

    async function copyImage(url) {
        console.log("Wriing to clipbard");  
    
        const response = await fetch(url);
        const blob = await response.blob();
    
        const item = new ClipboardItem({'image/png': blob});
        await navigator.clipboard.write([item]).then(function() {
          console.log("Copied to clipboard successfully!");
        }, function(error) {
          console.error("unable to write to clipboard. Error:");
          console.log(error);
        });
    }
    

    【讨论】:

      【解决方案2】:

      更完整的解决方案:

      在尝试解决这个问题时遇到了几个问题,我有一个适用于 Safari 的解决方案,也适用于所有其他浏览器。

      我们需要尝试两种场景(Safari 和其他场景):

      getImage (canvas, width = 200, height = 200) {
        return new Promise((resolve) => {
          const tmpCanvas = document.createElement('canvas')
          tmpCanvas.width = width
          tmpCanvas.height = height
          const ctx = tmpCanvas.getContext('2d')
          ctx.drawImage(canvas, 0, 0, canvas.width, canvas.height, 0, 0, width, height)
          tmpCanvas.toBlob(resolve)
        })
      }
      
      copyImg () {
       const canvas = document.getElementsByTagName('canvas')[0]
       if (canvas instanceof HTMLCanvasElement) {
         try {
           // Trying for only Safari browser
           const image = getImage(canvas)
           navigator.clipboard.write([new ClipboardItem({ 'image/png': image })])
           console.log('Copied')
         } catch (safariError: any) {
           try {
             // Trying for rest of browsers
             canvas.toBlob(blob => navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })]))
             console.log('Copied')
           } catch (anotherBrowserError: any) {
             console.log(safariError.message + ' - ' + anotherBrowserError.message)
           }
         }
       }
      

      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-18
        • 1970-01-01
        • 2011-04-26
        相关资源
        最近更新 更多