异步剪贴板 API“ClipboardItem 未定义” - Reactjs 将图像复制到剪贴板

Posted

技术标签:

【中文标题】异步剪贴板 API“ClipboardItem 未定义” - Reactjs 将图像复制到剪贴板【英文标题】:Async Clipboard API "ClipboardItem is not defined" - Reactjs copy image to Clipboard 【发布时间】:2021-04-06 04:55:08 【问题描述】:

我正在研究 React js,我使用 npm 使用 create-react-app 创建了我的应用程序。我试图构建一个按钮来获取图像并将其写入剪贴板。幸运的是,我发现 this npm 库似乎工作正常!但是让我一直在想为什么我不能使用 ¿built-in? Asynchronous Clipboard API 来复制图像(文本复制工作正常)。我阅读了一个非常有启发性的指南here,并继续阅读其他很棒的指南here,所以我尝试了所有建议的代码,那里和其他页面(尽管它们似乎并没有真正改变功能,我必须尝试)。每次尝试编译时,我都会遇到同样的错误:“'ClipboardItem' 未定义 no-undef”。例如一个代码是这个:

const response = await fetch('valid img url of a png image');
const blob = await response.blob();
await navigator.clipboard.write([new ClipboardItem( 'image/png': blob)]);

看起来很简单,很容易理解。问题是当您需要将数据放入剪贴板可以读取的形式中,使其成为 blob,因为我需要 ClipboardItem 构造函数,而我的应用程序似乎无法识别它。不断返回 ClipboardItem 没有定义,或者,如果我以某种方式定义它,当然说它不是构造函数。我尝试使用 Blob() 等其他构造函数,但遇到了同样的问题。最后一件事让我一直在想,因为我是编程世界的新手,如果有一些基本的东西,我不知道像这样的 Web API 与 node 或 Reactjs 的交互,如果有解决方案,当然!提前谢谢你们,你们太棒了!

编辑:按要求添加整个组件代码:

import React from "react";
  
function TestingClipAPI ()  

  async function handleScreenshot () 
    const response = await fetch('https://i.postimg.cc/d0hR8HfP/telefono.png');
    const blob = await response.blob();
    await navigator.clipboard.write([new ClipboardItem( 'image/png': blob)]);
  ;
  
  return (
    <div>
     <button onClick=handleScreenshot id="buttonID">test</button>
    </div>
  )
;

export default TestingClipAPI;

可能的问题:这可能是因为 CRA(Create-React-App)配置 - similar issue。可以完成库linked 之类的操作,创建一个画布并从那里复制图像。

解决方案或使其正常工作的方法:在使用 ClipboardItem 之前以这种方式调用:

const  ClipboardItem  = window;

注意:这也适用于存在相同问题的其他构造函数,例如 toBlob 和 htmlCanvasElement。

【问题讨论】:

【参考方案1】:

要寻找的东西:

    浏览器支持Clipboard HTTPS 或 localhost 上的安全源。 See this post. 如何调用函数 - 在 OP 的情况下 - onClick 和异步。

问题是 onClick 默认情况下不是异步的,您没有等待响应,并且您在 navigator.clipboard 中也有错字。

  const handleScreenshot = async () => 
    try 
      const response = await fetch(
        "https://i.postimg.cc/d0hR8HfP/telefono.png"
      );
      const blob = await response.blob();
      await navigator.clipboard.write([
        new ClipboardItem( "image/png": blob ),
      ]);
     catch (err) 
      console.error(err);
    
  

return (
  <button onClick=async () => await handleScreenshot() id="buttonID">
    test
  </button>
);

inline function 和以下是替代方案之间存在权衡。我个人会使用后一种方法。

function handleScreenshot() 
  async function screenShot() 
    try 
      const response = await fetch(
        "https://i.postimg.cc/d0hR8HfP/telefono.png"
      );
      const blob = await response.blob();
      await navigator.clipboard.write([
        new ClipboardItem( "image/png": blob ),
      ]);
     catch (err) 
      console.error(err);
    
  
  screenShot();


return (
  <button onClick=handleScreenshot id="buttonID">
    test
  </button>
);

最后,您可以返回chained promise。

【讨论】:

谢谢你!我很欣赏你的评论。我考虑过浏览器不支持它,但我有 Chrome 的最新版本,如果我没有读错 MDN 上的信息,它应该支持它,并且我使用 npm start 在端口/本地主机 3000 中运行它。我听从你的建议尝试一下,会进一步了解它。 我需要看看你是如何设置和调用你的复制函数的。您能否更新您的帖子以仅使用复制和粘贴功能以及返回浏览器的 JSX 来显示整个组件。 当然伙计,我刚刚创建了一个测试组件,它与 copy-img-clipboard 库一起工作得很好。我推迟了我的回答,因为我还测试了它使我的本地主机安全,但它又失败了。 我更新了anwser-onClicks 默认不是异步的。 谢谢老兄!我接受你的建议。我通常以链式方式使用承诺,如果它比尝试更好,你知道或有意见吗?同步的 onClick 似乎不是这里的问题,我用这种方式进行了测试,首先重写了我的代码,然后在出现拼写错误的情况下复制了你的代码,并以同样的方式失败。我还有另一个 onClick 事件,只需使句柄函数异步即可获取并正常工作。非常感谢你,我很感激你的努力,我想你也开始发痒了【参考方案2】:

只需在 ClipboardItem 前面添加窗口,如下所示

window.ClipboardItem(...)

【讨论】:

以上是关于异步剪贴板 API“ClipboardItem 未定义” - Reactjs 将图像复制到剪贴板的主要内容,如果未能解决你的问题,请参考以下文章

异步clipboard api

适用于所有 API 级别的 Android 剪贴板代码

Android:将文本复制到 API < 11 的剪贴板

cookie 可能会阻塞剪贴板 API

VB如何利用剪贴板复制、粘贴文件,用到啥API

VC++ win32 API 编程:如何将图像从剪贴板中取出并显示在窗口中?