Create a tab and add content script, resulting in you get permission error

On the base page of my Chrome extension, I need to do the following:

  • create a tab with an html page that is in my extension folder or dynamically generated by the background page;
  • after loading a new tab, paste the script content into it to use message passing;
  • After entering the script, send a message to a new tab with some data.

This always turns into an error:
tabs.executeScript: cannot access the contents of url "". The expansion manifest must request permission to access this host. or, if the page or script is stored in the .html and .js selected files in my extensions folder:
tabs.executeScript: cannot access the contents of the url "chrome-extension: //ehdjfh.../page.html". The expansion manifest must request permission to access this host.

An error is generated when chrome.tabs.executeScript() executed and the insertion of the contents of the script is blocked. (I will need this structure to transfer some big data to a tab that will be truncated if it is passed directly as a string to the html encoded URL)

Here is an example of code that can be used to test the behavior in a working extension, just copy-paste and download the extension in Chrome:

background.js

 chrome.browserAction.onClicked.addListener(function() { var getSampleHTML = function() { return 'javascript:\'<!doctype html><html>' + '<head></head>' + '<body>' + '<p id="myId">page created...</p>' + '</body>' + '</html>\''; }; // create a new tab with an html page that resides in extension domain: chrome.tabs.create({'url': getSampleHTML(), 'active': false}, function(tab){ var getSampleScript = function() { return 'chrome.extension.onRequest.addListener(' + 'function(request, sender, sendResponse) {' + 'if(request.action == "print_data" && sender.tab.id == ' + tab.id + '){' + 'var p = document.getElementById("myId");' + 'p += "<br>data received: " + request.data;' + '}' + '});' 'document.getElementById("myId").innerHTML += "<br>content-script loaded...";' }; // inject the content-script in the page created: chrome.tabs.executeScript(tab.id, {code: getSampleScript()}, function(){ // send the data to the content-script: chrome.tabs.sendRequest(tab.id, {action: "print_data", data: "some long data"}); }); }); }); 

manifest.json

 { "name": "ContentScript Injection Sample", "description": "", "version": "0.1", "permissions": ["tabs"], "background": { "persistent": false, "scripts": ["background.js"] }, "browser_action": { "default_title": "open a new tab and inject contentscript" }, "manifest_version": 2 } 
+6
source share
1 answer

ok, this is a possible solution thanks to @RobW and @ 方 觉 to indicate my mistake (my mistake was to consider the local web page open on the newly created tab as a regular web page, instead it has direct access to the API to the chrome.extension interface, for example, a popup):

background.js

 chrome.browserAction.onClicked.addListener(function() { // create a new tab with an html page that resides in extension domain: chrome.tabs.create({'url': chrome.extension.getURL("page.html"), 'active': false}, function(tab){ var selfTabId = tab.id; chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { if (changeInfo.status == "complete" && tabId == selfTabId){ // send the data to the page script: var tabs = chrome.extension.getViews({type: "tab"}); tabs[0].doSomething("some long data"); } }); }); }); 

page.html

 <!doctype html> <html> <head> </head> <body> <p id="myId">page created...</p> <script src="page.js" type="text/javascript"></script> </body> </html> 

page.js

 var alreadyRun = false; function doSomething(data){ if (!alreadyRun) { var p = document.getElementById("myId"); p.innerHTML += "<br>data received: " + data; // needed because opening eg. DevTools to inpect the page // will trigger both the "complete" state and the tabId conditions // in background.js: alreadyRun = true; } } document.getElementById("myId").innerHTML += "<br>script loaded..."; 

what I don't like about this solution is that using chrome.tabs.onUpdated.addListener() allows you to check whether the created tab is fully loaded, and thereby it starts for any change in the state of all opened tabs (this is useless. .. would be a great way to run validation only for the interested tab)

+5
source

Source: https://habr.com/ru/post/950994/


All Articles