Chrome 76 使用导航器将内容复制到剪贴板

tra*_*day 5 javascript clipboard navigator google-chrome-extension

我刚刚更新到 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);
Run Code Online (Sandbox Code Playgroud)

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

unable to write to clipboard. Error:

TypeError: Failed to execute 'write' on 'Clipboard': Iterator getter is not callable.
Run Code Online (Sandbox Code Playgroud)

奇怪的是,当我使用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);
Run Code Online (Sandbox Code Playgroud)

tra*_*day 3

好的,这是适合我的解决方案。在调用 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-permission not granted: " + result);
        }
    });
}, 3000);
Run Code Online (Sandbox Code Playgroud)

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

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);
    });
}
Run Code Online (Sandbox Code Playgroud)