Search code examples
javascriptjsongoogle-chrome-extensioncontextmenucode-injection

Extension manifest must request permission to access the respective host or a different Error


I'm trying to build an extension, and I'm having trouble injecting a function.

This is the link that I'm trying to work on, I suspect that the blob at the start is the problem.

blob:https://web.whatsapp.com/29d92fb3-d8e1-4c84-89af-b51668f5d2b3

This is my manifest.json file:

 {
    "name": "Image rotator",
    "version": "1.0",
    "manifest_version": 3,
    "description": "An extension to rotate images in web page.",
    "background": {
        "service_worker": "src/background.js"
      },
      "permissions": ["contextMenus","scripting","storage", "declarativeContent", "activeTab","<all_urls>"],
      "host_permissions": [
        "*://web.whatsapp.com/*"
      ]
      
}

This is my background.js file:

chrome.runtime.onInstalled.addListener(() => {
  chrome.contextMenus.create({
    "id": "rotateImage",
    "title": "Rotate Image",
    "contexts": ["image"]
  })
});

function injectedFunc() {
  document.getElementsByTagName("img").style.transform = "rotate(90deg)";
};

try {
  chrome.contextMenus.onClicked.addListener((tab) => {
    chrome.scripting.executeScript({
      target: {
        tabId: tab.id
      },
      function: injectedFunc
    });
  });
} catch (e) {
  console.error(e);
}

In this version, I get this error:

Error in event handler: TypeError: Error in invocation of scripting.executeScript(scripting.ScriptInjection injection, optional function callback): Error at parameter 'injection': Error at property 'target': Missing required property 'tabId'.

If I change the onClicked method to this version:

try{
chrome.contextMenus.onClicked.addListener((info, tab) => {
    if(info.menuItemId === "rotateImage"){
    chrome.scripting.executeScript({
        target: {tabId: tab.id},
        function: injectedFunc
      });}
  });
} catch (e) {
    console.error(e);
  }

I get this error:

Uncaught (in promise) Error: Cannot access contents of the page. Extension manifest must request permission to access the respective host.


Solution

  • The second variant was the correct one, according to this I needed to add "match_origin_as_fallback": true, to the manifest.json file inside "content_script" to make the browser be able to read the blob URL.

    But it still didn't work, I needed to add the injected code to a different file than the background.js.

    With some help from Reddit (Thanks Ibrahim_AA), the sendMessage and onMessage API did the work. Here is the full solution:

    manifest.json:

    {
      "name": "Image rotator",
      "version": "1.0",
      "manifest_version": 3,
      "description": "An extension to rotate images in web page.",
      "background": {
        "service_worker": "src/background.js"
      },
      "permissions": ["contextMenus","scripting"],
      "host_permissions": [
        "*://web.whatsapp.com/*"
      ],
      "content_scripts": [
        {
          "matches": ["*://web.whatsapp.com/*"],
          "match_origin_as_fallback": true,
          "js": ["contentScript.js"]
        }
      ]
    }
    

    background.js:

    chrome.runtime.onInstalled.addListener(() => {
        chrome.contextMenus.create({
            "id": "rotateImage",
            "title": "Rotate Image",
            "contexts": ["image"]
        })
    });
    
    try{
        chrome.contextMenus.onClicked.addListener((info, tab) => {
            if(info.menuItemId === "rotateImage"){
                chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
                    chrome.tabs.sendMessage(tabs[0].id, {
                        type: "rotateImage",
                    });
                });
            }
        });
    } catch (e) {
        console.error(e);
    }

    contentScript.js

    function rotateImage() {
      document.getElementsByTagName("img")[0].style.transform = "rotate(90deg)";
    };
    
    chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
        if (msg.type === 'rotateImage') {
            rotateImage();
        }
    });

    Hope it helps anyone that comes across this problem.