javascriptgoogle-chromesynchronize

Synchronous call in Google Chrome extension


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.


Solution

  • 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"]);