1

I'm creating a simple Chrome Extension with a popup, background script and a content script which I want to inject programmatically.

When a user clicks a button I want the extension to create a new tab with a url provided from the user and execute a content script on that page.

My approach is to send a message from the popup to my background script and run the following code:

chrome.tabs.create({ url }, () => {
  chrome.tabs.executeScript({ file: 'content.js' });
});

But this fails and tells me that my extension doesn't have the correct permissions, even though I have permissions set to ["activeTab"].

The problem is that I would prefer not to have permissions to execute on every url, e.g. ["https://*/*", "http://*/*"] (It would probably seem suspicious, but might be my only solution).

I have set up an example repo here: https://github.com/adambrgmn/test-extension. It can be loaded into Chrome as an extension.

Has anyone else encountered this problem? Any workarounds?

  • You'll have to use the wide permissions or switch to [optional permissions](https://developer.chrome.com/extensions/permissions). Quoting the documentation: The activeTab permission gives an extension temporary access to the **currently active tab** when the user invokes the extension - for example by clicking its browser action. Access to the tab lasts until the tab is navigated or closed. – wOxxOm Oct 23 '18 at 12:12

2 Answers2

0

activeTab gives you permission to the current tab only when the user activates your extension from the tab, not any new tabs created from it.

You'll probably have to request permission to that URL before opening the tag, for example:

// in your popup.js
// Listen to your "create tab" button
document.querySelector('button').addEventListener('click', () => {
    // Get the URL they entered
    const urlEntered = document.querySelector('input').value;

    // Request the permission
    chrome.permissions.request({origins: [urlEntered]}, granted => {
        if (granted) {
            // Create the tab only if it was granted
            chrome.tabs.create({ url }, tab => {
                chrome.tabs.executeScript(tab.id, { file: 'content.js' });
            });
        } else {
            alert('You need to grant permission')
        }
    });
});
fregante
  • 29,050
  • 14
  • 119
  • 159
0

In manifestv3, you can do this. It's a hack, but it works, injecting scripts to generated tabs consistently:

function _func(res){
    setTimeout( () => {
    // Do things with the page.
    }, 3000);
}
chrome.tabs.create({url: 'https://www.example.com'}).then((tab) => {
    setTimeout(() => {
        chrome.scripting.executeScript({
            target: {tabId: tab.id},
            func: _func //,
            // I used args in my case, you dont have to. args: [msg.content]
        })
    }, 3000)
});
A. Abramov
  • 1,823
  • 17
  • 45