在 Chrome 扩展 V3 中复制到剪贴板

发布于 2025-01-11 13:12:42 字数 1035 浏览 0 评论 0原文

我正在开发一个 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 扩展程序作为 Service Worker 运行。所以看来我无法访问 DOM 文档并且没有授予 writeText 权限。还有人有其他建议吗?

谢谢。

I am developing a chrome extension V3. I want to copy content to clipboard in my JS file.
The manifest.json as below,

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

I have try 2 solution for copy feature.

Solution 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);
  

The result:

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

Solution 2:

navigator.clipboard.writeText(str);

The result:

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

The chrome extension is run as a service worker. So it seems I can't access DOM document and have no grant of writeText. Does anyone have another suggestion?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

猛虎独行 2025-01-18 13:12:42

我将遵循 wOxxOm 给您的出色建议,并通过具体示例对其进行详细说明。您想要做的是让 ContentScript.js 在任何带有网页的活动选项卡上运行,因为您无法从 backGround.js 访问 DOM,然后向此脚本发送消息,您可以从其中复制到剪贴板。

manifest.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 中处理。

back.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);
}

I'll follow the excellent suggestion wOxxOm gave you, elaborating it in a concrete example. What you want to do is have a ContentScript.js that runs on any active tab with a web page, since you can't access the DOM from the backGround.js, and then send a message to this script, from where you would copy to the clipboard.

manifest.json

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

From the background.js, you would send a message, that will be handled in the ContentScript.js

background.js

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

In the contentScript.js, you would catch the message and copy it to the clipboard.

content.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);
}
黯然#的苍凉 2025-01-18 13:12:42

我不是 Chrome 插件方面的专家,但我相信请求 并不是最佳做法。
相反,我通过请求 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 的说法)

I'm not an expert in Chrome addons, but I believe that requesting <all_urls> is not best practice.
Instead, I got something to work by request activeTab instead, ditching the content scripts and injecting code to the active tab instead.
Manifest:

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

Background:

// 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],
  });
}

So contentCopy is injected to the active tab and executed with the text I want to copy to clipboard.
Works well, and saves on problematic permissions (according to Google)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文