2013-08-25 78 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'。希望有所幫助。 –

相關問題