【问题标题】:Copy to clipboard in chrome extension V3在 chrome 扩展 V3 中复制到剪贴板
【发布时间】:2023-01-31 15:29:03
【问题描述】:

我正在开发一个 chrome 扩展 V3。我想将内容复制到我的 JS 文件中的剪贴板。
如下所示的 manifest.json,

    "background" :{
        "service_worker" :"eventPage.js"
    },
    "permissions" : [
        "contextMenus",
        "clipboardWrite"      
    ]

我已经尝试了 2 个复制功能解决方案。

解决方案 1:

    const el = document.createElement('textarea');
    el.value = str;
    el.setAttribute('readonly', '');
    el.style.position = 'absolute';
    el.style.left = '-9999px';
    document.body.appendChild(el);
    el.select();
    document.execCommand('copy');
    document.body.removeChild(el);
  

结果:

Error in event handler: ReferenceError: document is not defined at copyToClipboard 

解决方案 2:

navigator.clipboard.writeText(str);

结果:

Error in event handler: TypeError: Cannot read properties of undefined (reading 'writeText')

chrome 扩展作为服务工作者运行。所以看起来我无法访问 DOM 文档并且没有 writeText 的授权。有人有其他建议吗?

谢谢。

【问题讨论】:

  • 您必须打开一个可见页面,其中包含您的扩展程序的 html 文件,然后将文本复制到那里。
  • 所以我不能在右键单击和上下文菜单中实现该功能,对吗?
  • 您必须 a) 打开一个带有扩展程序 html 文件的可见页面,然后将文本复制到那里,或者 b) 将内容脚本声明/注入到活动选项卡(或任何带有网页的选项卡)中,然后将文本复制到那里.

标签: javascript google-chrome-extension copy-paste


【解决方案1】:

我会遵循 wOxxOm 给你的极好的建议,在一个具体的例子中详细说明它。你想要做的是让一个 ContentScript.js 在带有网页的任何活动选项卡上运行,因为你无法从 backGround.js 访问 DOM,然后从你要复制的地方向这个脚本发送消息到剪贴板。

清单.json

    "background" :{
        "service_worker" :"eventPage.js"
    },
    "permissions" : [
        "contextMenus",
        "clipboardWrite"      
    ],
   "content_scripts": [ // this is what you need to add
      {
         "matches": [
            "<all_urls>"
         ],
         "js": ["content.js"]
      }
   ],

从 background.js,您将发送一条消息,该消息将在 ContentScript.js 中处理

背景.js

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    chrome.tabs.sendMessage(tabs[0].id, 
        {
            message: "copyText",
            textToCopy: "some text" 
        }, function(response) {})
})

在 contentScript.js 中,您将捕获消息并将其复制到剪贴板。

内容.js

chrome.runtime.onMessage.addListener( // this is the message listener
    function(request, sender, sendResponse) {
        if (request.message === "copyText")
            copyToTheClipboard(request.textToCopy);
    }
);

async function copyToTheClipboard(textToCopy){
    const el = document.createElement('textarea');
    el.value = textToCopy;
    el.setAttribute('readonly', '');
    el.style.position = 'absolute';
    el.style.left = '-9999px';
    document.body.appendChild(el);
    el.select();
    document.execCommand('copy');
    document.body.removeChild(el);
}

【讨论】:

  • 谢谢。通过您的示例代码,我已经解决了问题!
  • 别客气!如果对您有帮助,能否请您将答案标记为已接受?这将帮助我和其他人快速找到解决方案。
  • 复制您的代码时,我不断收到相同的错误:Unchecked runtime.lastError: Could not establish connection。接收端不存在。
  • 意思是当background.js通过chrome.tabs.sendMessage向active tab发送消息时,页面上的content.js没有准备好或者没有重新加载。安装扩展后尝试重新加载页面。还有,你的manifest.json里面的eventPage.js换成background.js了吗?仔细检查您创建的文件的名称
  • 要添加的两个细节: * 提供的解决方案确实对我有用,但不推荐使用 document.execCommand('copy');,我无法设法让 Navigator.clipboard.writeText('') 工作。 * 可以使用 chrome.scripting.executeScript( 动态注入 js
【解决方案2】:

我不是 Chrome 插件方面的专家,但我认为请求 &lt;all_urls&gt; 不是最佳做法。
相反,我通过请求 activeTab 得到了一些工作,而不是放弃内容脚本并将代码注入活动选项卡。
显现:

...
    "permissions": [
      "clipboardWrite"
      "activeTab",
      "scripting"
    ],
    "background": {
        "service_worker": "background.js"
    },
...

背景:

// To be injected to the active tab
function contentCopy(text) {
  navigator.clipboard.writeText(text);
}

async function copyLink(text, tab) {
  // Format as a whatsapp link
  const link = await getWhatsAppLink(text);
  chrome.scripting.executeScript({
    target: { tabId: tab.id },
    func: contentCopy,
    args: [link],
  });
}

所以 contentCopy 被注入到活动选项卡并执行我想复制到剪贴板的文本。
运行良好,并节省了有问题的权限(根据 Google 的说法)

【讨论】:

    猜你喜欢
    • 2012-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-08
    • 2014-10-28
    • 2014-06-06
    • 1970-01-01
    相关资源
    最近更新 更多