2009-04-01 8 views
6

vamos a suponer que tengo el siguiente marcado:¿Cómo inyecto javascript a una página en IE 8?

<div id="placeHolder"></div> 

y tengo una variable de JavaScript jsVar que contiene un poco de margen de beneficio y algo de JavaScript.

Mediante el uso de Mootools 1.1 Puedo inyectar el contenido de JavaScript en el marcador de posición así:

$('placeHolder').setHTML(jsVar); 

Esto funciona en Firefox, Opera, e incluso Safari y el margen de beneficio resultante es la siguiente:

<div id="placeHolder"> 
    <strong>I was injected</strong> 
    <script type="text/javascript"> 
     alert("I was injected too!"); 
    </script> 
</div> 

Sin embargo, en IE 8 me sale el siguiente: hay alguna

<div id="placeHolder"> 
    <strong>I was injected</strong> 
</div> 

Es forma de inyectar el JavaScript en IE 8 o el modelo de seguridad me prohíbe hacer esto en absoluto?

me trataron sugerencia de utilizar

document.getElementById("placeHolder").innerHTML = jsVar; 

en lugar del código MooTools Luca Matteis' y me da el mismo resultado. Esto no es un problema de MooTools.

Respuesta

1

No estoy seguro acerca de MooTools, pero ¿has probado innerHTML?

document.getElementById ("placeHolder"). InnerHTML = jsVar;

+0

Acabo de intentarlo. Obtuve los mismos resultados. Pero gracias, esto demuestra que no es un problema de mootools. – adolfojp

1

Es posible que tenga que evaluar el contenido de la etiqueta del script. Esto requeriría un análisis para encontrar scripts en su jsVar y eval (whatsBetweenTheScriptTags).

+0

Ese es el camino que tendré que seguir. Actualmente estoy usando eval o ejecutando una función temporal en el contenido de los elementos del script en el elemento maestro de marcador de posición. Como IE 8 no inserta las secuencias de comandos en el marcado, tendré que analizarlas en el nivel variable. Funciona. – adolfojp

5

Este MSDN post se refiere específicamente a cómo usar innerHTML para insertar javascript en una página. Tiene razón: IE considera que esto es un problema de seguridad, por lo que necesita pasar por ciertos aros para obtener la secuencia de comandos ... probablemente los piratas informáticos puedan leer esta publicación de MSDN lo mejor que podamos, así que no sé cómo ¿Por qué MS considera que esta capa adicional de indirección es "segura", pero estoy divagando?

Desde el artículo de MSDN:

<HTML> 
<SCRIPT> 
function insertScript(){ 
    var sHTML="<input type=button onclick=" + "go2()" + " value='Click Me'><BR>"; 
    var sScript="<SCRIPT DEFER>"; 
    sScript = sScript + "function go2(){ alert('Hello from inserted script.') }"; 
    sScript = sScript + "</SCRIPT" + ">"; 
    ScriptDiv.innerHTML = sHTML + sScript; 
}  
</SCRIPT> 
<BODY onload="insertScript();"> 
    <DIV ID="ScriptDiv"></DIV> 
</BODY> 
</HTML> 

Si es posible, es posible que desee considerar el uso de una etiqueta de secuencia de comandos de carga inyectada document.write para aumentar la seguridad y reducir la incompatibilidad entre navegadores. Entiendo que esto puede no ser posible, pero vale la pena considerarlo.

+1

http://forums.microsoft.com/msdn/showpost.aspx?postid=909379&siteid=1 Script en IE es un elemento NoScope. Y los elementos de NoScope se eliminan desde el comienzo del HTML analizado antes de inyectar innerHTML o insertAdjacentHTML. Suena no considerado como un problema de seguridad. –

1

Como IE se niega a insertar el contenido de forma predeterminada, tendrá que ejecutarlo usted mismo, pero al menos puede engañar a IE para que haga el análisis por usted.

Simplemente use string.replace() para cambiar todas las etiquetas <script> por <textarea class="myScript" style="display:none">, conservando el contenido. A continuación, pegue el resultado en un innerHTML de un div.

Una vez hecho esto, puede utilizar

div.getElementsByTagName("textarea") 

para obtener todas las áreas de texto, de bucle a través de ellos y buscar su clase de marcador ("myScript" en este caso), y, o bien eval(textarea.value) o (new Function(textarea.value))() que sus seres queridos acerca de.

1

Nunca probé, que acaba de llegar a mi mente ... ¿Se puede probar lo siguiente:

var script = document.createElement('script'); 
script.type = 'text/javascript'; 

script.innerHTML = '//javascript code here'; // not sure if it works 
// OR 
script.innerText = '//javascript code here'; // not sure if it works 
// OR 
script.src = 'my_javascript_file.js'; 

document.getElementById('placeholder').appendChild(script); 

Puede utilizar la misma técnica (DOM) para insertar el formato HTML.

4

Así es como lo hicimos en nuestro sitio hace aproximadamente un año para hacerlo funcionar en IE. Estos son los pasos:

  • añadir el código HTML para un huérfano elemento DOM
  • buscar el nodo huérfano para etiquetas de script (orphan.getElementsByTagName)
  • obtener el código de esos nodos de script (guardar para más adelante), y luego eliminarlos de la huérfana
  • añadir el sobrante hTML que se encuentra en el huérfano y añadirlo al marcador de posición (placeholder.innerHTML = orphan.innerHTML)
  • crear un elemento de guión y añadir el código almacenado a ella (scriptElem .text = 'alerta ("mi código");')
  • continuación, agregue el elemento de secuencia de comandos para el DOM (preferiblemente la cabeza), luego lo elimina
 
function set_html(id, html) { 
    // create orphan element set HTML to 
    var orphNode = document.createElement('div'); 
    orphNode.innerHTML = html; 

    // get the script nodes, add them into an arrary, and remove them from orphan node 
    var scriptNodes = orphNode.getElementsByTagName('script'); 
    var scripts = []; 
    while(scriptNodes.length) { 
     // push into script array 
     var node = scriptNodes[0]; 
     scripts.push(node.text); 

     // then remove it 
     node.parentNode.removeChild(node); 
    } 

    // add html to place holder element (note: we are adding the html before we execute the scripts) 
    document.getElementById(id).innerHTML = orphNode.innerHTML; 

    // execute stored scripts 
    var head = document.getElementsByTagName('head')[0]; 
    while(scripts.length) { 
     // create script node 
     var scriptNode = document.createElement('script'); 
     scriptNode.type = 'text/javascript'; 
     scriptNode.text = scripts.shift(); // add the code to the script node 
     head.appendChild(scriptNode); // add it to the page 
     head.removeChild(scriptNode); // then remove it 
    } 
} 

set_html('ph', 'this is my html. alert("alert");'); 
0

Cuando usted dice que "funciona" en esos otros navegadores, Qué quiere decir que recibe el mensaje alert emergente, ¿O simplemente te refieres a que la etiqueta <script> lo convierte en el árbol DOM?

Si su objetivo es el primero, tenga en cuenta que el comportamiento de inyectar html con <script> incrustado es muy dependiente del navegador. Por ejemplo, en los últimos MooTools puedo intentar:

$(element).set('html', '<strong>Foo</strong><script>alert(3)</script>') 

y hacer no conseguir la ventana emergente, no en IE (7), no en FF (3) (sin embargo hacer obtener el nodo <script> en el DOM con éxito). Para obtenerlo en alert en todos los navegadores, debe hacerlo como this answer.

1

Lo siento, tal vez me falta algo aquí, pero con esto siendo una pregunta de mootools 1.11, ¿por qué no usas assets.js?

// you can also add a json argument with events, etc. 
new Asset.javascript("path-to-script.js", { 
    onload: function() { 
     callFuncFromScript(); 
    }, 
    id: "myscript" 
}); 

no es una de las razones por las que estamos utilizando un marco no tener que reinventar la rueda todo de nuevo ...

por lo que el 'otro' es el contenido en cuestión ¿Cómo lo conseguiste?Si a través de la clase de solicitud, que puede hacer lo que quiere bien mediante el uso de las opciones:

{ 
    update: $("targetId"), 
    evalScripts: true, 
    evalResponse: false 
} 
2

me he encontrado con los mismos problemas con Internet Explorer 8 (e IE7) La única manera de que pudiera inyectar dinámicamente un guión (con una src) es mediante el uso de un temporizador:

source = "bla.js"; 

setTimeout(function() { 
      // run main code 
      var s = document.createElement('script'); 
      s.setAttribute('src', source); 
      document.getElementsByTagName('body')[0].appendChild(s); 
     }, 50); 

Si tiene código en línea que desea inyectar, se puede eliminar el temporizador y utilizar el método de "texto" para el elemento de script:

s.text = "alert('hello world');"; 

Sé que mi respuesta ha llegado bastante tarde; sin embargo, es mejor tarde que nunca :-)

0

Y mi comentario es muy tarde, pero también es el más acertado aquí. La razón por la que no ve el contenido <script> en ejecución es porque no agregó el atributo defer a la etiqueta <script>. El artículo de MSDN dice específicamente que debe hacer eso para que se ejecute la etiqueta <script>.