I know that waiting for an asynchronous method is stupid, one should use callbacks instead. But what if an third party API forces you to be synchronous?
I'm developing a Chrome Extension that will prevent the user from visiting websites that's already open in another tab. I basically need to cancel requests based on the urls in open tabs. I want to use chrome.webRequest.onBeforeRequest
like this:
function onBeforeRequest(details) {
var websiteAlreadyOpenInOtherTab;
// Here i want to set `websiteAlreadyOpenInOtherTab` by using the `chrome.tabs`
// API. It's asynchronous though and that's my problem. I cant return a value
// from an asynchronous method call.
if (websiteAlreadyOpenInOtherTab) {
return { cancel: true };
}
}
chrome.webRequest.onBeforeRequest.addListener(
onBeforeRequest,
{ urls: ['<all_urls>'], types: ['main_frame'] },
['blocking']);
Hopefully you see my dilemma in the code above. I need to return an object based on the result of asynchronous method calls. Is it possible to achieve this?
I know that waiting for an asynchronous method is stupid, one should use callbacks instead. But what if an third party API forces you to be synchronous?
I'm developing a Chrome Extension that will prevent the user from visiting websites that's already open in another tab. I basically need to cancel requests based on the urls in open tabs. I want to use chrome.webRequest.onBeforeRequest
like this:
function onBeforeRequest(details) {
var websiteAlreadyOpenInOtherTab;
// Here i want to set `websiteAlreadyOpenInOtherTab` by using the `chrome.tabs`
// API. It's asynchronous though and that's my problem. I cant return a value
// from an asynchronous method call.
if (websiteAlreadyOpenInOtherTab) {
return { cancel: true };
}
}
chrome.webRequest.onBeforeRequest.addListener(
onBeforeRequest,
{ urls: ['<all_urls>'], types: ['main_frame'] },
['blocking']);
Hopefully you see my dilemma in the code above. I need to return an object based on the result of asynchronous method calls. Is it possible to achieve this?
Share edited May 23, 2017 at 10:34 CommunityBot 11 silver badge asked Feb 28, 2013 at 0:00 SvenSven 9338 silver badges16 bronze badges 4-
Can't you listen to all
chrome.tabs
changes and havewebsiteAlreadyOpenInOtherTab
already containing the right value whenonBeforeRequest
is called? – Bergi Commented Feb 28, 2013 at 0:12 - I think you're approaching the problem incorrectly. Firstly, if things need to be asynchronous, then instead of requiring a synchronous response, work within the model and use an asynchronous callback in which if you decide the tab shouldn't be open, you close it. There is a separate API function to close tabs, you don't need to return false just from the onbeforerequest... – davin Commented Feb 28, 2013 at 0:23
- @davin: But that'll lead to "tab flickering" or something, a pletely different behaviour (and a request would be sent) – Bergi Commented Feb 28, 2013 at 0:46
-
@Bergi Yeah, almost.
onBeforeRequest
can't contain the right value (because I won't know it beforeonBeforeRequest
is called. But I could maintain some kind of structure that knows about open tabs. It's a walk-around alright. @davin +1 on @Bergi's arguments. It's unacceptable to send a request and close the tab in my use case. The request should be canceled. But thanks for your suggestion anyway. :) – Sven Commented Feb 28, 2013 at 5:54
1 Answer
Reset to default 6Maybe you can solve the problem by keeping track of the tab URLs?:
- When the app starts, get all open tab URLs by using
chrome.tabs.query
- Subscribe to
chrome.tabs.onUpdated
andchrome.tabs.onRemoved
and add/remove/update the URLs when they change.
Some kind of code example based on the documentation:
var tabUrlHandler = (function() {
// All opened urls
var urls = {},
queryTabsCallback = function(allTabs) {
allTabs && allTabs.forEach(function(tab) {
urls[tab.id] = tab.url;
});
},
updateTabCallback = function(tabId, changeinfo, tab) {
urls[tabId] = tab.url;
},
removeTabCallback = function(tabId, removeinfo) {
delete urls[tabId];
};
// init
chrome.tabs.query({ active: true }, queryTabsCallback);
chrome.tabs.onUpdated.addListener(updateTabCallback);
chrome.tabs.onRemoved.addListener(removeTabCallback);
return {
contains: function(url) {
for (var urlId in urls) {
if (urls[urlId] == url) {
return true;
}
}
return false;
}
};
}());
Now you should be able to ask the tabUrlHandler
directly in your onBeforeRequestMethod
:
function onBeforeRequest(details) {
var websiteAlreadyOpenInOtherTab = tabUrlHandler.contains(details.url);
if (websiteAlreadyOpenInOtherTab) {
return { cancel: true };
}
}
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744935816a4602015.html
评论列表(0条)