I am trying to change the contents of a page based on the output of a xhr call. I am sending a message from content.js making the xrh call in the background js file and then passing the output to content.js which alters the content of the page.
From my content.js
file I am doing the following.
var s = document.createElement('script');
s.src = chrome.extension.getURL('src/content/main.js');
(document.head || document.documentElement).appendChild(s);
In my main.js
I am doing
chrome.runtime.sendMessage({
method: 'GET',
action: 'xhttp',
url: myurl
}, function(responseText) {
console.log("Response Text is ", responseText);
});
And in my bg.js
I have the following
chrome.runtime.onMessage.addListener(function(request, sender, callback) {
if (request.action == "xhttp") {
var xhttp = new XMLHttpRequest();
var method = request.method ? request.method.toUpperCase() : 'GET';
xhttp.onload = function() {
callback(xhttp.responseText);
};
xhttp.onerror = function() {
// Do whatever you want on error. Don't forget to invoke the
// callback to clean up the communication port.
callback('Error');
};
xhttp.open(method, request.url, true);
if (method == 'POST') {
xhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}
xhttp.send(request.data);
return true; // prevents the callback from being called too early on return
}
});
The issue I am facing is I keep getting the error Invalid arguments to connect.
for chrome.runtime.sendMessage
function.
I am not sure what I am missing. Any help us is greatly appreciated.
You have been trying to inject your content script into the page with a <script>
tag.
When you do it, your script ceases to be a content script: it executes in the context of the page, and loses all elevated access to Chrome API, including sendMessage
.
You should read up on isolated world concept and this question about page-level scripts.
To use jQuery, you should not rely on the copy provided by the page - it's in another context and therefore unusable. You need to include a local copy of jQuery with your files and load it before your script:
If you're using the manifest to inject scripts, you can add jQuery to the list before your script:
"content_scripts": [
{
matches: ["http://*.example.com/*"],
js: ["jquery.js", "content.js"]
}
],
If you are using programmatic injection, chain-load your scripts to ensure the load order:
chrome.tabs.executeScript(tabId, {file: "jquery.js"}, function() {
chrome.tabs.executeScript(tabId, {file: "content.js"});
});
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