Reputation: 83
i'm trying to design a chrome extension, it has to inject a script into a web page, this script intercepts json responses, and send them to the background script.
Keep in mind i'm not used to js i might be doing this wrong, so, in my manifest i have :
"background": {
"scripts": ["background.js"],
"persistent": true
},
"content_scripts": [
{
"matches": ["*://url*"],
"run_at": "document_start",
"js": ["inject.js"]
}
],
"web_accessible_resources": ["injected.js"],
in my background script i handle the messages that way :
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.type) {
switch(request.type) {
case "THIS_REQUEST_TYPE":
do_stuff(request.foo, request.bar);
break;
...................
inject.js's purpose is to inject injected.js into a webpage, and now it's also doing relay for messages that goes from injected.js to background.js, i inject injected.js that way :
var s = document.createElement('script');
s.src = chrome.extension.getURL('injected.js');
s.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(s);
Now, to get messages from injected.js to my background script i basically use :
window.postMessage(msgdata, "*");
This send messages from injected.js to inject.js, then in inject.js i'm able to get those messages with :
window.addEventListener("message", function(event) {
Then i can finally send those messages to my background script, this time using :
chrome.runtime.sendMessage(
I found no possible way to directly send messages from injected.js to background.js, the informations available on chrome's documentation are perfectly fine to send messages from inject.js to background.js, but aren't working otherwise, i tried several online solutions and the one i use is the only one i was able to get working.
Anyway, this works, i'm able to send json responses from injected.js to inject.js to background.js and parse them in my background script.
The thing is, i hate having to do it that way, json responses can be really long, i'm already filtering responses in injected.js so that only those who are useful are getting sent, but still sometimes i have to send copy of responses that are 591109 characters long ! So, having to send twice responses that long is kinda ugly, i want this to be efficient and fast.
Anyone have an idea about this ?
Upvotes: 3
Views: 4587
Reputation: 73506
Your injected.js is running in a script
DOM element so it's just an unprivileged web page script.
To use chrome.runtime.sendMessage
directly from a web page script you would have to declare the allowed URL patterns in externally_connectable and you can allow <all_urls>
since Chrome 107.
In earlier versions only specific domains are allowed, so I would use your approach, although with a CustomEvent (and a random event name most likely) instead of message
which can be intercepted by the page scripts or other extensions - it's not security that I'm concerned with here, but rather a possibility of breaking some site that assumes the message data is in a certain format (e.g. string), not compatible with the one you use (e.g. object).
You can also use chrome.debugger API to attach to the tab and intercept the JSON response in your background script, but that will show a notification above the tab about it being debugged.
Anyway, unless you see your extension slowing down the page (in devtools profiler or by manually measuring the time spent in your code), there's no need to worry.
FWIW, in Firefox you can read the response directly via browser.webRequest.filterResponseData.
Upvotes: 6