acceder al contenido del iframe desde el script de contenido de la extensión de Chrome

Estoy haciendo un complemento para hacer algunas transformaciones en la interfaz. sigo recibiendo unsafe javascript attempt to access frame with url.... Domains, protocols and ports must match (problema típico entre sitios)

Pero al ser una extensión, debería tener acceso al contenido del iframe. http://code.google.com/chrome/extensions/content_scripts.html ...

¿Alguien sabe cómo acceder a sus contenidos para que puedan ser capturados?

preguntado el 04 de julio de 12 a las 09:07

¿Qué es exactamente lo que quiere hacer? En la mayoría de los casos, puede agregar "all_frames":true En el correo electrónico “Su Cuenta de Usuario en su Nuevo Sistema XNUMXCX”. "content_scripts" de su archivo de manifiesto y codifique la lógica específica de la página en su secuencia de comandos de contenido. -

@RobW agregando all_frames:true hará que content_script se ejecute una vez en todos los marcos internos. Esto complicará mucho la lógica. Solo quiero acceder al contenido de los marcos internos a través de content_script. (como: script_contenido --> página_objetivo --> contenido_interno) -

Eso no es posible: un script de contenido no puede acceder a ninguna de las páginas window objeto (incluidos los marcos). Inyectar un script de contenido con "all_frames": false, en el que establece una bandera. Luego, inyecte un script con all_frames": true, donde se comprueba la existencia de esta bandera. Si el indicador no existe, suponga que el script de contenido se ejecuta en un marco. A continuación, puede aplicarle una lógica específica del marco y utilizar el paso de mensajes para pasar los datos adquiridos al script de contenido principal. -

mmm ok gracias :p pero podrías haber agregado eso en una respuesta para marcarlo, ya estaba pensando en hacerlo como dijiste pero esperaba que existiera el acceso directo -

No estaba seguro de lo que querías. Para iframes profundamente anidados, la solución sugerida no funcionaría. Voy a publicar un ejemplo conciso. -

2 Respuestas

Por lo general, no hay una forma directa de acceder a un origen diferente window objeto. Si quieres segura comunicarse entre secuencias de comandos de contenido en diferentes marcos, debe enviar un mensaje a la página de fondo que, a su vez, envía el mensaje a la pestaña.

Aquí hay un ejemplo:

Parte de manifest.json:

"background": {"scripts":["bg.js"]},
"content_scripts": [
    {"js": ["main.js"], "matches": ["<all_urls>"]},
    {"js": ["sub.js"], "matches": ["<all_urls>"], "all_frames":true}
]

main.js:

var isTop = true;
chrome.runtime.onMessage.addListener(function(details) {
    alert('Message from frame: ' + details.data);
});

sub.js:

if (!window.isTop) { // true  or  undefined
    // do something...
    var data = 'test';
    // Send message to top frame, for example:
    chrome.runtime.sendMessage({sendBack:true, data:data});
}

Script de fondo 'bg.js':

chrome.runtime.onMessage.addListener(function(message, sender) {
    if (message.sendBack) {
        chrome.tabs.sendMessage(sender.tab.id, message.data);
    }
});

Un método alternativo es utilizar chrome.tabs.executeScript in bg.js para activar una función en el script de contenido principal.

Documentación relevante

Respondido el 20 de junio de 20 a las 10:06

Su declaración "No hay forma de acceder a ninguno de los objetos de ventana de una página". no parece ser completamente exacto. Acabo de crear una extensión básica y puedo acceder a window.frames y obtener acceso DOM completo a los marcos en el mismo origen. ¿Quizás esto ha cambiado desde que escribiste tu respuesta? Parece que esto todavía está en desarrollo y no está completamente documentado. Ver: code.google.com/p/chromium/issues/detail?id=20773 - kzahel

@kzahel Al momento de escribir, window.frames[i] para todos is no estaba definido. De hecho, esto ha sido arreglado por un tiempo. Sin embargo, la política del mismo origen todavía se aplica, por lo que la respuesta sigue siendo válida, al menos para la pregunta formulada (donde el OP estaba encontrando problemas con el acceso al marco entre dominios). - Rob W

@stt Gracias por traer la falla en mi respuesta a mi atención. Los revisores lo rechazaron, pero edité mi respuesta de todos modos. - Rob W

Necesito acceder a una variable definida por la página en la que se ejecuta mi script de contenido; ¿Cómo? - sologusti

Entiendo que esta es una vieja pregunta, pero recientemente pasé medio día para resolverla. Por lo general, la creación de un iframe se ve así:

var iframe = document.createElement('iframe');
iframe.src = chrome.extension.getURL('iframe-content-page.html');

Este marco tendrá un origen diferente con una página y no podrá obtener su DOM. Pero si crea un iframe solo para el aislamiento de css, puede hacerlo de otra manera:

var iframe = document.createElement('iframe');
document.getElementById("iframe-parent").appendChild(iframe);
iframe.contentDocument.write(getFrameHtml('html/iframe-content-page.html'));
.......
function getFrameHtml(htmlFileName) {
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("GET", chrome.extension.getURL(html/htmlFileName), false);
    xmlhttp.send();

    return xmlhttp.responseText;
}
.......
"web_accessible_resources": [   
    "html/htmlFileName.html",
    "styles/*",
    "fonts/*"
]

Después de eso, puede usar iframe.contentDocument para acceder al DOM de iframe

Respondido 22 Abr '16, 14:04

Todavía no he probado esto, solo me pregunto si esto solo devuelve el código HTML del iframe, o le da una referencia real al DOM de ese iframe. - chris-jr

Será la referencia real al DOM: puede obtener/establecer valores de entradas, ocultar divs, etc. Eugene Titarchuk

Enfoque inteligente. Acabo de votar. También me gustaría saber si queremos acceder al revés. p.ej; padre (pestaña actual) dom en iframe?? - estudiante de wp

no, esto funciona solo porque estoy creando iframe sin src, por lo que el dominio será el mismo que la página principal. - Eugene Titarchuk

@EugeneTitarchuk ¡Gracias! Exactamente lo que necesita cuando inyecta bootstrap en la extensión de gmail. - dikirill

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.