I'm writing a chrome extension and I'm struggling to pass an object back from the main page to the context script. I can't seem to access the window's variables.
ContextScript
//STORE DATA TO CHROME STORAGE ON EVENT
//create hidden input
var hiddenInput = document.createElement("input");
hiddenInput.setAttribute("type", "text");
hiddenInput.setAttribute("id", "__HIDDEN__RESULT__");
//add input to page
var currentItem = document.body.appendChild(hiddenInput);
//event to be fired on click
currentItem.onclick = function() {
//get the global variable window.listOfCourses and stick it in storage
chrome.storage.local.set({'dataVault' : window.listOfCourses});
};
//inject script into page
var s = document.createElement("script");
s.src = chrome.extension.getURL("gradebook.js");
s.onload = function() {this.parentNode.removeChild(this);};
(document.head||document.documentElement).appendChild(s);
Injected Script
function processData()
{
window.listOfCourses = [];
for (i=0; i < window.completedData.length; i++)
{
//get data and add to window.listOfCourses
}
var myElement = document.getElementById("__HIDDEN__RESULT__")
myElement.click();
}
The injected script pulls information from a page, sticks it in an object set as global variable, then finally it fires the onclick event for the input.
All of this works. However, when the click event fires and runs currentItem.onclick() and tries to access window.listOfCourses, it doesn't see the variable. I'm confused why I'm not able to see my global variables anymore.
Any help would be greatly appreciated!
When sending a message to the content script, we need to specify which tab to send it to. Therefore, we need to retrieve the active tab information first, and then use tabs. sendMessage . To use the tabs API and to have access to the active tab, you need to add tabs and activeTab under permissions in your manifest.
To inject a content script programmatically, your extension needs host permissions for the page it's trying to inject scripts into. Host permissions can either be granted by requesting them as part of your extension's manifest (see host_permissions ) or temporarily via activeTab.
executeScript() Injects a script into a target context. The script is run at document_idle by default. Note: This method is available in Manifest V3 or higher in Chrome and Firefox 101. In Safari and Firefox 102+, this method is also available in Manifest V2.
Communication between extensions and their content scripts works by using message passing. Either side can listen for messages sent from the other end, and respond on the same channel.
The global variables of a content script and a page-level injected script are isolated.
Content scripts execute in a special environment called an isolated world. They have access to the DOM of the page they are injected into, but not to any JavaScript variables or functions created by the page. It looks to each content script as if there is no other JavaScript executing on the page it is running on. The same is true in reverse: JavaScript running on the page cannot call any functions or access any variables defined by content scripts.
Emphasis mine.
To pass the data to your content script, you don't have to employ extra DOM elements. You just need custom DOM events.
// Content script
// Listen for the event
window.addEventListener("FromPage", function(evt) {
/* message is in evt.detail */
}, false);
// Page context
var message = {/* whatever */};
var event = new CustomEvent("FromPage", {detail: message});
window.dispatchEvent(event);
See this answer for far more details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With