为什么某些网站的webNavigation Listener失败? [英] Why webNavigation Listener failed for some websites?
问题描述
我正在尝试使用chrome扩展程序来从Web of Science中获取一些数据.第一步,我想创建一个新选项卡并等待它加载.因此,在创建标签后,我添加了一个webNavigation侦听器.我发现听众效果很好 仅适用于某些网站.如果我将目标网址(科学网络)用作以下代码,则不会收到警报窗口.但是,如果我使用目标" https://stackoverflow.com/questions/ask ",它将成功发出警报.为什么会这样?谁能告诉我原因?真的很感谢.
I am trying to use chrome extension to get some data from web of science. In one step, I want to create a new tab and wait until it loaded. So I add a webNavigation Listener after creating the tab. I found the listener works well only for some websites. If I use the target url (web of science) as the code below, I won't get the alert window. But if I use the target "https://stackoverflow.com/questions/ask", it gives the alert successfully. Why this happens? Could anyone advice the reason to me? Really thankful to it.
background.js
background.js
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
var activeTab = tabs[0];
tabId = activeTab.id;
chrome.tabs.sendMessage(tabId, {"message": "clicked_browser_action"});
});
});
var link = 'https://apps.webofknowledge.com/OneClickSearch.do?product=UA&search_mode=OneClickSearch&excludeEventConfig=ExcludeIfFromFullRecPage&SID=7ENVgUT3nRKp41VVlhe&field=AU&value=Leroux,%20E.'; // failed in this url
//var link = 'https://stackoverflow.com/questions/ask'; //success in this url
function listener1(){
chrome.webNavigation.onCompleted.removeListener(listener1);
chrome.tabs.sendMessage(tabId, {"message": "to content"});
alert('listener succeed');
}
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.joke == 'content initial'){
chrome.tabs.create({ url: link });
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
var activeTab = tabs[0];
tabId = activeTab.id;
});
//alert(link);
chrome.webNavigation.onCompleted.addListener(listener1, {url: [{urlMatches : link}]});
}
}
)
content.js
content.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if( request.message === "clicked_browser_action" ) {
console.log('content initial');
chrome.runtime.sendMessage({joke: 'content initial'}, function(response) {
});
}
}
)
manifest.json
manifest.json
{
"manifest_version": 2,
"name": "citation",
"version": "1",
"background": {
"scripts": ["background.js"],
"persistent": false
},
"browser_action": {},
"content_scripts": [{
"matches": ["<all_urls>"],
"run_at": "document_idle",
"js": ["content.js"]
}],
"permissions": [
"downloads",
"webNavigation",
"tabs",
"<all_urls>"
]
}
推荐答案
主要问题是urlMatches
是RE2语法中的正则表达式,您可以在
The main problem is that urlMatches
is a regular expression in RE2 syntax as you can see in the documentation so various special symbols in the URL like ?
are interpreted differently. Solution: use urlEquals
or other literal string comparisons.
还有其他问题:
- API是异步的,因此将来将以无法预测的顺序创建和查询选项卡.解决方案:使用create()的回调.
- 所有选项卡均在webNavigation侦听器中报告,而不仅仅是活动的选项卡,因此从理论上讲,存在一个问题,即在不同的选项卡中报告了两个相同的URL.同样,API过滤参数也不能使用
#hash
部分来处理URL解决方案:记住要在变量中监视的选项卡ID,并在侦听器中对其进行比较,然后在过滤器中明确剥离#hash部分. - 该网站可能会重定向页面的最终URL,因此由于您的过滤器,它可能不会得到报告.解决方案:仅在过滤器中指定主机名.
- 向您发送消息或执行导航的选项卡可能处于无效状态.解决方案:使用侦听器参数中的选项卡ID.
- The API is asynchronous so the tabs are created and queried later in the future in no predictable sequence. Solution: use the callback of create().
- All tabs are reported in webNavigation listener, not just the active one, so theoretically there's a problem of two identical URLs being reported in different tabs. Also the API filtering parameter cannot handle URLs with
#hash
part Solution: remember the tab id you want to monitor in a variable and compare it in the listener, and explicitly strip #hash part in the filter. - The site may redirect the final URL of the page so it may not get reported due to your filter. Solution: specify only the host name in the filter.
- The tab that sends you messages or performs navigation may be inactive. Solution: use the tab id in the listener's parameters.
chrome.browserAction.onClicked.addListener(tab => {
chrome.tabs.sendMessage(tab.id, {message: 'clicked_browser_action'});
});
var link = '...............';
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
if (msg.joke === 'content initial') {
chrome.tabs.create({url: link}, tab => {
chrome.webNavigation.onCompleted.addListener(function onCompleted(info) {
if (info.tabId === tab.id && info.frameId === 0) {
chrome.webNavigation.onCompleted.removeListener(onCompleted);
chrome.tabs.sendMessage(tab.id, {message: 'to content'});
console.log('listener succeeded');
}
}, {
url: [{urlPrefix: new URL(link).origin + '/'}],
});
});
}
});
注意:
- 如果只需要按需处理,请避免在所有URL的manifest.json中声明
content_scripts
.在这种情况下,请使用程序注入. - 在断点或后台页面的
console.log()
等devtools中,而不是alert()使用适当的调试(更多信息)
- Avoid declaring
content_scripts
in manifest.json for all URLs if you only need processing on demand. Use programmatic injection in such cases. - Instead of alert() use the proper debugging in devtools like breakpoints or
console.log()
of the background page (more info).
这篇关于为什么某些网站的webNavigation Listener失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!