with ventana transparente open misma emergente ejemplo centrada abrir javascript google-chrome-extension

ventana - window.open javascript popup



¿Cómo puedo verificar qué pestaña abrió una ventana(emergente)? (2)

El problema

He tenido este problema desde hace meses, pero el concepto es bastante sencillo: quiero bloquear algún Sitio Malicioso ™ para que no abra pestañas o ventanas emergentes mediante programación.

Con la API chrome.tabs , puedo escuchar con onCreated cuando se onCreated una nueva pestaña, y puedo verificar fácilmente quién (es decir, qué pestaña) abrió esa pestaña en particular accediendo a la propiedad openerTabId del objeto Tab pasado a la función de devolución de llamada.

Ahora, me gustaría hacer exactamente lo mismo cuando se crea una nueva ventana : Me gustaría saber qué pestaña abrió la ventana (si la hubiera, porque el usuario también podría haberla abierto), verifique su URL para ver si es el Sitio Malicioso ™ y actúa en consecuencia (es decir, bloquea la ventana emergente). Intenté hacerlo exactamente de la misma manera: solicite la matriz de pestañas en la nueva ventana y verifique su propiedad en la ventana de openerTabId , pero desafortunadamente esa propiedad no está definida. Busqué en la documentación y busqué en Google durante horas, pero, lamentablemente, parece que no hay una forma sencilla de comprobar quién abrió una ventana.

Una solución muy torpe.

Dicho lo anterior, la única forma en que pude hacer algo que se acercara a lo que realmente quiero, es la siguiente:

  1. Cada vez que se crea una nueva ventana , su ID se agrega a una matriz llamada windowWatchlist .
  2. Cada vez que se actualiza una pestaña (NB: actualizada, no se crea), se inyecta un script dentro de ella para verificar su document.referrer , que debe contener la URL del sitio que abrió la pestaña: si la URL del remitente contiene la dirección del Malicious Site ™ Quiero bloquear las ventanas emergentes, la ventana se cierra y se elimina de la lista de windowWatchlist .
  3. Cada vez que se cierra una ventana , si su ID está en la lista de windowWatchlist , se elimina de ella.

Aquí está el código (que se ejecuta en mi script background.js ):

// Called on chrome.windows.onCreated function watchPopupWindow(window) { windowWatchlist.push(window.id); console.log(''Added window #'' + window.id + '' to watchlist.''); } // Called on chrome.windows.onRemoved function unwatchPopupWindow(windowID) { var index = windowWatchlist.indexOf(windowID); // If the windowID is in the watchlist: if (index != -1) { // Remove it: windowWatchlist.splice(index, 1); console.log(''Removed window #'' + windowID + '' from watchlist.''); } } // Called on chrome.tabs.onUpdated function blockPopupWindow(tabID, info, tab) { // If this tab is in a window which is in the watchlist: if (windowWatchlist.indexOf(tab.windowId) != -1 && info.url && info.url != ''about:blank'') { // Check the referrer of this tab: chrome.tabs.executeScript(tabID, {code: ''document.referrer;''}, function(ref) { // If the referrer is the malicious site to block: if (ref && ref[0] && ref[0].indexOf("http://MALICIOUS-SITE.XXX") != -1) { // Close the popup window: chrome.windows.remove(tab.windowId, function() { console.log(''Blocked popup window #'' + tab.windowId + ''.''); if (chrome.runtime.lastError) console.error(chrome.runtime.lastError.message); });; } }); } } var windowWatchlist = []; chrome.windows.onCreated.addListener(watchPopupWindow, {windowTypes: [''popup'']}); chrome.windows.onRemoved.addListener(unwatchPopupWindow, {windowTypes: [''popup'']}); chrome.tabs.onUpdated.addListener(blockPopupWindow);

Ahora, puede que se esté preguntando: ¿por qué necesita todo este lío solo para verificar un referente? ¿No podría simplemente verificar las pestañas contenidas en la ventana cuando se abre la ventana y verificar su referencia directamente dentro de la devolución de llamada de chrome.window.onCreated ? Esa es una pregunta inteligente, y la respuesta es simple: el problema es que no puedo verificar la referencia de las pestañas justo cuando se crean, porque casi siempre necesitan algo de tiempo para cargar , y la referencia no se carga hasta que comienza la página. Cargando dentro de la pestaña. Por lo tanto, necesito verificar cuándo se actualiza una pestaña, ver si su ventana está en mi lista de seguimiento y luego verificar su referencia. Esta es la razón por la que chrome.tabs.onUpdated es necesario, ya que dispara sus escuchas cada vez que una pestaña cambia de estado (por ejemplo, tab.status cambia de "loading" a "complete" ).

¿Por qué esta solución no funciona?

La razón por la que califico a esta solución de "torpe" y la razón por la que realmente no funciona debería ser clara para cualquiera con alguna experiencia en el desarrollo de JavaScript y web: document.referrer no es confiable en absoluto , y muchas veces undefined está undefined o (en caso de redirecciones múltiples) no es la correcta. Esto hace que mi script falle aproximadamente el 90% de las veces, porque no puede determinar si la ventana emergente fue abierta por Malicious Site ™ o no.

Además, el Sitio Malicioso ™ a menudo abre ventanas emergentes con URL about:blank o sin URL, y solo cuando se cargan, les inyecta datos, lo que las hace prácticamente imposibles de detectar, incluso con chrome.tabs.onUpdated que no lo hace. despedir a cualquier oyente en esta situación.

Podría decidir bloquear cualquier ventana emergente con la URL about:blank o undefined , y esto es lo que estoy haciendo en este momento, pero es un compromiso bastante malo, ya que termino cerrando ventanas emergentes abiertas por cualquier sitio que use este método, y no solo el sitio malicioso ™ que quiero bloquear.

En conclusión

Mi pregunta es simple, pero no conozco su solución: ¿alguien conoce algún otro método más confiable que pueda usarse para detectar quién abrió una nueva ventana? No se me ocurre nada, ¿tal vez podría ser posible algo utilizando la API chrome.webRequest ? Realmente no lo sé. Durante meses he estado aceptando el hecho de que una solución simple simplemente no era posible, y esperé impotentemente una actualización o algo así, pero en realidad nunca pensé en preguntar aquí, porque el problema estaba por encima de la competencia de un programador promedio de Chrome Extension. , pero ojalá estuviera equivocado.

ACTUALIZACIÓN : la solución para inyectar un script dentro del sitio y reemplazar la función window.open con otra cosa no es viable: si se carga un <iframe> sin un atributo src , pero con un DOM ya escrito dentro del atributo srcdoc , Chrome no ejecutará un script de contenido dentro de él, incluso si la llamada a chrome.tabs.executeScript se realiza con allFrames: true , e incluso si el script de contenido se declara dentro del manifiesto de la extensión.


Como ya estás haciendo inyección de código, esto es lo que yo haría.

Inyecte el código para anular window.open y window.postMessage que window.postMessage to child window les diga quién los abrió. También deberá inyectar código para escuchar el efecto de window.addEventListener(''message'', messageHandler) que decidirá si deben window.close() .

En segundo lugar, creo que simplemente anularía window.open y ni siquiera abriría las ventanas secundarias si no desea permitir que un sitio abierto abra Windows.


Encontré el mismo problema y encontré el evento webNavigation.onCreatedNavigationTarget que produce la pestaña de origen / id de marco cuando se abre una nueva ventana.

Solución encontrada en este post: ¿Es posible determinar el abridor de una pestaña dentro de una extensión de Google Chrome?