2013-08-25 81 views
5

为了显示横幅广告交换中的广告,我正在加载包含链接到广告服务器的iframe的webview。通过一些JavaScript,我可以让广告链接目标为“_blank”,这样广告就会在单独的浏览器窗口中打开,否则它会在同一个小型web视图中打开。如何从Chrome浏览器的Chrome浏览器中的链接打开新窗口

但是它不工作,我得到这个在控制台:

<webview>: A new window was blocked. 

任何想法如何做到这一点?

回答

12

事情是,默认情况下,web视图不会让客人打开任意窗口。相反,它会发出一个'newwindow'事件,你可以拦截并决定如何处理它。在一个不太可怕的形式,这将是这个样子:

chrome.app.runtime.onLaunched.addListener(function() { 
    chrome.app.window.create(
    'main.html', 
    { 'width': 1000, 'height': 1000 }, 
    function(win) { 
     win.contentWindow.onload = function() { 
     var webview = win.contentWindow.document.querySelector('#my_webview'); 
     webview.addEventListener('newwindow', function(e) { 
      e.preventDefault(); 
      // e.targetUrl contains the target URL of the original link click 
      // or window.open() call: use it to open your own window to it. 
      // Something to keep in mind: window.open() called from the 
      // app's event page is currently (Nov 2013) handicapped and buggy 
      // (e.g. it doesn't have access to local storage, including cookie 
      // store). You can try to use it here and below, but be prepare that 
      // it may sometimes produce bad results. 
      chrome.app.window.create(e.targetUrl, ...); 
     }); 
     }; 
    } 
); 
}); 

我认为这应该为你工作,因为你所描述的情况。在“newwindow e.targetUrl:

在更恶劣的情况下,某些网站可能会打开新的窗口/标签是这样的:

function open(href) { 
    var w = window.open('', '_blank'); 
    w.opener = null; 
    w.document.write(
     '<META HTTP-EQUIV="refresh" content="0; url=' + href + '">'); 
    w.document.close(); 
} 

如果这样的网站被包裹在网页视图,一切都变得更加困难'上面的处理程序将包含“关于:空白”,所以没有修改代码将打开一个空白的窗口/选项卡。拦截从来宾随后重定向,应用程序也将不得不使用chrome.webRequest API(文档似乎是唯一的扩展,但是API已经可以在稳定的渠道打包应用程序,太):

chrome.app.runtime.onLaunched.addListener(function() { 
    chrome.app.window.create(
    'main.html', 
    { 'width': 2000, 'height': 1000 }, 
    function(win) { 
     win.contentWindow.onload = function() { 
     var webview = win.contentWindow.document.querySelector('#webview'); 
     webview.addEventListener('newwindow', function(e) { 
      e.preventDefault(); 
      if (e.targetUrl !== 'about:blank') { 
      // Easy case where the original link or window.open() 
      // already contains a target URL. 
      newWindow_openInTab(e.targetUrl); 
      } else { 
      // Harder case where the guest first opens a blank 
      // window and then redirects it via a 
      // 'META HTTP-EQUIV="refresh"'. 
      newWindow_openInTabAndInterceptRedirect(e.window); 
     }); 
     }; 
    } 
); 
}); 

function newWindow_openInTab(url) { 
    chrome.app.window.create(url, ...); 
} 

function newWindow_openInTabAndInterceptRedirect(newWindow) { 
    // Create an invisible proxy webview to listen to redirect 
    // requests from |newWindow| (the window that the guest is 
    // trying to open). NOTE: The proxy webview currently has to 
    // live somewhere in the DOM, so we append it to the body. 
    // This requirement is in the process of being eliminated. 
    var proxyWebview = document.createElement('webview'); 
    document.body.appendChild(proxyWebview); 

    // Listen to onBeforeRequest event (chrome.webRequest API) 
    // on proxyWebview in order to intercept newWindow's redirects. 
    var onBeforeRequestListener = function(e) { 
    // Only consider top-level non-blank redirects. 
    if (e.type === "main_frame" && e.url !== 'about:blank') { 
     chrome.app.window.create(e.url, ...); 
     // Don't need proxyWebview anymore. 
     document.body.removeChild(proxyWebview); 
     // Handled this redirect: cancel further processing. 
     return { cancel: true }; 
    } else { 
     // Ignored this redirect: proceed with default processing. 
     return { cancel: false }; 
    } 
    }; 
    proxyWebview.onBeforeRequest.addListener(
    onBeforeRequestListener, 
    { urls: [ "*://*/*" ] }, 
    [ 'blocking' ] 
); 

    // Attach |newWindow| to proxyWebview. From the original 
    // webview guest's point of view, the window is now opened 
    // and ready to be redirected: when it does so, the redirect 
    // will be intercepted by |onBeforeRequestListener|. 
    newWindow.attach(proxyWebview); 
} 
+0

我对newwindow事件并不陌生,谢谢。第二种方法也是一个很好的窍门。 –

+0

我并不是说第二种方法是解决原始问题的方法。我想说的是,有些网站(例如Gmail)有时会使用此技术来打开新标签并将它们引导至目标网址。我会更新我的答案,使其更加清晰,并为这个更困难的案例添加解决方案。 –

+0

我刚才想到,我所说的一切都是基于假设你正在处理target ='_ blank'链接,而实际上你自己是在向链接添加target ='_ blank'。在这种情况下,您的问题可以通过直接在web视图上使用webRequest API来解决(因为它在第二个示例中用于代理webview),所以根本没有必要使用代理webview或者听取'newwindow'。希望有所帮助。 –

相关问题