Synchronous call in Google Chrome extension
Asked Answered
I

2

9

I'm working on Google Chrome extension, which has to block/redirect some outgoing requests. For this purpose, I use chrome.webRequest.onBeforeRequest listener. To decide, whether to block request or not, I need some information about the tab request is sent from. I can get it using chrome.tabs.get(integer tabId, function callback), but callback is asynchronous, which means it may be called after the value is returned from onBeforeRequest listener.

chrome.webRequest.onBeforeRequest.addListener(function(details){
 chrome.tabs.get(details.tabId, function(tab){
  // get info from tab
 }); 
 // based on info from tab return redirect or not
}), {
 urls: ["<all_urls>"],
 types: ["main_frame"]
}, ["blocking"]);

Is there a way to synchronize the call? Or maybe some other option.

Ingathering answered 19/3, 2013 at 11:34 Comment(1)
ever figure this out?Giraud
D
14

Another answer on Stack Overflow recommends keeping track of the tabs outside of your listener function, which avoids this problem entirely.

Example code:

/* 
 * --------------------------------------------------
 * Keep list of tabs outside of request callback
 * --------------------------------------------------
 */
var tabs = {};

// Get all existing tabs
chrome.tabs.query({}, function(results) {
    results.forEach(function(tab) {
        tabs[tab.id] = tab;
    });
});

// Create tab event listeners
function onUpdatedListener(tabId, changeInfo, tab) {
    tabs[tab.id] = tab;
}
function onRemovedListener(tabId) {
    delete tabs[tabId];
}

// Subscribe to tab events
chrome.tabs.onUpdated.addListener(onUpdatedListener);
chrome.tabs.onRemoved.addListener(onRemovedListener);

/* 
 * --------------------------------------------------
 * Request callback
 * --------------------------------------------------
 */
// Create request event listener
function onBeforeRequestListener(details) {
    // *** Remember that tabId can be set to -1 ***
    var tab = tabs[details.tabId];

    // Respond to tab information
}

// Subscribe to request event
chrome.webRequest.onBeforeRequest.addListener(onBeforeRequestListener, {
    urls: ["<all_urls>"],
    types: ["main_frame"]
}, ["blocking"]);
Deuterogamy answered 26/2, 2014 at 21:43 Comment(2)
Cheers. I added a bounty on this because I had a similar problem with executeScript, and this was the way to go. (Although I had to also do some rebinding of requestListeners)Giraud
What effect does this have on performance? I've switched to using this method as it 'just works' for me but I've got an uneasy feeling about performance issues for users with a lot of tabs.Sharpwitted
O
0
chrome.runtime.onMessage.addListener((message, rawSender, sendResponse) => {

        // here, you can call sendResponse method in any where asynchronous.

        return true;    // 这是重点,it's important
    }
);

// it also fit chrome.webRequest.onBeforeRequest.addListener

official document

Oligosaccharide answered 22/4, 2020 at 13:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.