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