Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Synchronous message passing in chrome extensions?

I'm trying to block a script file from loading on user defined websites. To block a script file I'm using beforeload event and event.preventDefault(); in content script which works fine as long as I already know website list. My problem is I don't know website list in advance, so to get the website list I'm sending a request to background page but response is asynchronous and unusable.

Is there any synchronous message passing in Chrome Extensions that I possibly missed in Google's docs?

// my (simplified) code from content script:
document.addEventListener("beforeload", function(event)
{
  chrome.extension.sendRequest({fnc:"is_owner"}, function(response)
  {
    // asynchronous response is not usable because
    // all scripts have already been loaded
    if (response.is_owner) event.preventDefault();
  });
}, true);
like image 914
Igor Jerosimić Avatar asked Oct 22 '10 11:10

Igor Jerosimić


People also ask

Can Chrome extensions communicate with each other?

In addition to sending messages between different components in your extension, you can use the messaging API to communicate with other extensions.

Is there a Chrome extension for Google messages?

Chrome Extension - Send and receive text messages via Google Chrome - TxtSync.

How do I communicate with chrome extensions?

Chrome has documentation on sending messages from webpages to chrome extensions. You add an “externally_connectable” object to your manifest. This will specify which webpages you want to allow to communicate with your extension (in this case, localhost, since I was developing on my machine).

How do you send a message from the background script to a popup script?

forEach((tab) => { chrome. tabs. sendMessage( tab.id, youtPayload, function (response) { // do something here if you want } ); }); }); That's it!


2 Answers

Unfortunately there isn't. There is a bug report opened about lack of synchronous message passing, maybe if enough people star it they will do something about it.

like image 130
serg Avatar answered Sep 28 '22 17:09

serg


You can use the HTML5 File API (navigator.webkitTemporaryStorage or the older deprecated window.webkitStorageInfo with the TEMPORARY option) to store settings to a file. This part is asynchronous but you can do it from background or your options page or popup. This API can change on you since it isn't standardized yet. Since it's temporary storage, your background page may need to run persistent to keep chrome from deleting the file.

Then from your content script you can use synchronous XMLHttpRequest to get the file from "filesystem:" + chrome.extension.getURL("temporary/" + filename). The "filesystem:" prefix on the url is rather important.

Best bet is to use the chrome.storage API (or localStorage) for your settings and hook the onChanged event from that to update the temporary file. If you need to reload the page after a settings change, you'll want to do that in the callback from the FileSystem write operation so you know the content script can see the change.

It doesn't require any special permissions in the manifest. I've personally tested this in chrome 35 but I know it worked in earlier versions as well. I don't know the minimum version requirement, however. I recall seeing a mention of a security change related regression in chrome 33 where it didn't work but was quickly fixed.

I've seen a few other workarounds (e.g. redirect to blob url or data uri from onBeforeWebRequest) for getting settings into content scripts prior to the page's own scripts running but as far as I can tell they've all been intentionally broken in recent versions of chrome due to general XSS and extension security improvements.

like image 22
protocol6 Avatar answered Sep 28 '22 16:09

protocol6