Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
479 views
in Technique[技术] by (71.8m points)

javascript - 阻止Chrome扩展程序中的onBeforeNavigate事件指示的导航(Block the navigation indicated by an onBeforeNavigate event in a Chrome extension)

I want to restrict the browser to within a set of URLs.(我想将浏览器限制在一组URL内。)

I'm using:(我正在使用:) chrome.webNavigation.onBeforeNavigate.addListener(functon(details){ if (notAllowed(details.url)) { // Do something to stop navigation } }); I know that I can cancel chrome.webRequest.onBeforeRequest .(我知道可以取消chrome.webRequest.onBeforeRequest 。) But, I don't want to block requests, like XHR or any other.(但是,我不想阻止请求,例如XHR或其他任何请求。) I want this filter to be applied only for navigation.(我希望此过滤器仅适用于导航。) For the user, it should looks like, the link (eg <a href="http://...">foo</a> ) click event was stopped.(对于用户而言,链接事件(例如<a href="http://...">foo</a> )的单击事件已停止。)   ask by dkiselev translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The following extension adds a listener to webNavigation.onCompleted which is used to remember, indexed by tabId, both the most recent URL in frameId==0 for which the event is fired, and the prior URL.(以下扩展将一个侦听器添加到webNavigation.onCompleted ,该侦听器用于记住由tabId索引的,触发了事件的frameId==0最新URL和先前的URL(由tabId索引)。)

A listener is added to webNavigation.onBeforeNavigate which watches for matching URLs, in this case, stackexchange.com .(侦听器被添加到webNavigation.onBeforeNavigate该手表匹配的URL,在这种情况下, stackexchange.com 。) If the URL matches, the tab URL is updated, via tabs.update , to navigate back to the last URL for which a webNavigation.onCompleted event was fired.(如果URL匹配,则通过tabs.update来更新选项卡URL,以导航回为其触发webNavigation.onCompleted事件的最后一个URL。) If the onBeforeNavigate event is for a frameId other than 0 , then the tab is navigated to the previous URL for which a onCompleted event was fired for frameId==0 .(如果onBeforeNavigate事件是针对非0frameId ,则该选项卡将导航到先前的URL,对于该URL,已针对frameId==0触发了onCompleted事件。) If the prior URL was not used, then we could get into a loop where the current URL is repeatedly re-loaded due to the URL in one of its frames matching the URL we are blocking.(如果未使用先前的URL,那么我们可能会陷入一个循环,其中由于其框架之一中的URL与我们阻止的URL相匹配,因此会重复重新加载当前URL。) A better way to handle this would be to inject a content script to change the src attribute for the frame.(处理此问题的更好方法是注入内容脚本以更改框架的src属性。) We would then need to handle frames within frames.(然后,我们需要处理框架内的框架。) blockNavigation.js :(blockNavigation.js :) //Remember tab URLs var tabsInfo = {}; function completedLoadingUrlInTab(details) { //console.log('details:',details); //We have completed loading a URL. createTabRecordIfNeeded(details.tabId); if(details.frameId !== 0){ //Only record inforamtion for the main frame return; } //Remember the newUrl so we can check against it the next time // an event is fired. tabsInfo[details.tabId].priorCompleteUrl = tabsInfo[details.tabId].completeUrl; tabsInfo[details.tabId].completeUrl = details.url; } function InfoForTab(_url,_priorUrl) { this.completeUrl = (typeof _url !== 'string') ? "" : _url; this.priorCompleteUrl = (typeof _priorUrl !== 'string') ? "" : _priorUrl; } function createTabRecordIfNeeded(tabId) { if(!tabsInfo.hasOwnProperty(tabId) || typeof tabsInfo[tabId] !== 'object') { //This is the first time we have encountered this tab. //Create an object to hold the collected info for the tab. tabsInfo[tabId] = new InfoForTab(); } } //Block URLs function blockUrlIfMatch(details){ createTabRecordIfNeeded(details.tabId); if(/^[^:/]+://[^/]*stackexchange.[^/.]+//.test(details.url)){ //Block this URL by navigating to the already current URL console.log('Blocking URL:',details.url); console.log('Returning to URL:',tabsInfo[details.tabId].completeUrl); if(details.frameId !==0){ //This navigation is in a subframe. We currently handle that by // navigating to the page prior to the current one. // Probably should handle this by changing the src of the frame. // This would require injecting a content script to change the src. // Would also need to handle frames within frames. //Must navigate to priorCmpleteUrl as we can not load the current one. tabsInfo[details.tabId].completeUrl = tabsInfo[details.tabId].priorCompleteUrl; } var urlToUse = tabsInfo[details.tabId].completeUrl; urlToUse = (typeof urlToUse === 'string') ? urlToUse : ''; chrome.tabs.update(details.tabId,{url: urlToUse},function(tab){ if(chrome.runtime.lastError){ if(chrome.runtime.lastError.message.indexOf('No tab with id:') > -1){ //Chrome is probably loading a page in a tab which it is expecting to // swap out with a current tab. Need to decide how to handle this // case. //For now just output the error message console.log('Error:',chrome.runtime.lastError.message) } else { console.log('Error:',chrome.runtime.lastError.message) } } }); //Notify the user URL was blocked. notifyOfBlockedUrl(details.url); } } function notifyOfBlockedUrl(url){ //This will fail if you have not provided an icon. chrome.notifications.create({ type: 'basic', iconUrl: 'blockedUrl.png', title:'Blocked URL', message:url }); } //Startup chrome.webNavigation.onCompleted.addListener(completedLoadingUrlInTab); chrome.webNavigation.onBeforeNavigate.addListener(blockUrlIfMatch); //Get the URLs for all current tabs when add-on is loaded. //Block any currently matching URLs. Does not check for URLs in frames. chrome.tabs.query({},tabs => { tabs.forEach(tab => { createTabRecordIfNeeded(tab.id); tabsInfo[tab.id].completeUrl = tab.url; blockUrlIfMatch({ tabId : tab.id, frameId : 1, //use 1. This will result in going to '' at this time. url : tab.url }); }); }); manifest.json :(manifest.json :) { "description": "Watch webNavigation events and block matching URLs", "manifest_version": 2, "name": "webNavigation based block navigation to matched URLs", "version": "0.1", "permissions": [ "notifications", "webNavigation", "tabs" ], "background": { "scripts": ["blockNavigation.js"] } }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...