2009-04-01 12 views
6

Lets supporre che ho la seguente marcatura:Come si inserisce javascript su una pagina su IE 8?

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

e ho una variabile JavaScript jsVar che contiene un po 'di markup e un po' JavaScript.

Utilizzando Mootools 1.1 Posso iniettare il contenuto JavaScript nel segnaposto in questo modo:

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

Questo funziona in Firefox, Opera, e anche Safari e il markup risultante assomiglia a questo:

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

Tuttavia, su IE 8 ottengo il seguente:

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

c'è qualche modo di iniettare il codice JavaScript su IE 8 o il modello di sicurezza mi impedisce di farlo?

Ho provato il suggerimento Luca Matteis' di utilizzare

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

al posto del codice MooTools e ottengo lo stesso risultato. Questo non è un problema di MooTools.

risposta

1

Non sono sicuro di MooTools, ma avete provato innerHTML?

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

+0

Ho appena provato. Ottengo gli stessi risultati. Ma grazie, questo dimostra che non è un problema di mootools. – adolfojp

1

Potrebbe essere necessario valutare il contenuto del tag di script. Ciò richiederebbe l'analisi per trovare gli script in jsVar e eval (whatsBetweenTheScriptTags).

+0

Questo è il percorso che dovrò seguire. Attualmente sto usando eval, o eseguendo una funzione temporanea sul contenuto degli elementi dello script nell'elemento del segnaposto master. Poiché IE 8 non inserisce gli script nel markup, dovrò analizzarli a livello di variabili. Funziona. – adolfojp

5

Questo MSDN post indica in particolare come utilizzare innerHTML per inserire javascript in una pagina. Hai ragione: IE considera questo un problema di sicurezza, quindi ti richiede di saltare attraverso certi cerchi per ottenere lo script iniettato ... presumibilmente gli hacker possono leggere questo post MSDN nel miglior modo possibile, quindi sono in perdita per quanto riguarda perché la MS considera questo strato aggiuntivo di riferimento indiretto "sicuro", ma sto divagando.

Dall'articolo 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> 

Se possibile, si potrebbe desiderare di considerare l'utilizzo di un tag script iniettato carico document.write per aumentare la sicurezza e ridurre cross-browser incompatibilità. Capisco che questo potrebbe non essere possibile, ma vale la pena considerarlo.

+1

http://forums.microsoft.com/msdn/showpost.aspx?postid=909379&siteid=1 Script in IE è un elemento NoScope. Gli elementi di NoScope vengono rimossi dall'inizio dell'HTML analizzato prima di essere iniettati con innerHTML o insertAdjacentHTML. Sembra non essere considerato un problema di sicurezza. –

1

Poiché IE rifiuta di inserire il contenuto per impostazione predefinita, è necessario eseguirlo da soli, ma è possibile almeno trarre in inganno IE per eseguire l'analisi per conto dell'utente.

Utilizzare semplicemente string.replace() per scambiare tutti i tag <script> per <textarea class="myScript" style="display:none">, preservando il contenuto. Quindi incollare il risultato in un innerHTML di un div.

Dopo aver fatto questo, è possibile utilizzare

div.getElementsByTagName("textarea") 

per ottenere tutte le textarea, ciclo attraverso loro e cercare per la classe marcatore ("myScript" in questo caso), e sia eval(textarea.value) o (new Function(textarea.value))() quelli che ti interessano di.

1

ho mai provato, è solo venuto in mente ... si può provare il seguente:

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); 

È possibile utilizzare la stessa tecnica (DOM) per inserire codice HTML.

4

Ecco come l'abbiamo fatto sul nostro sito circa un anno fa per farlo funzionare in IE. Ecco i passaggi:

  • aggiungere il codice HTML per un orfano elemento DOM
  • cercare il nodo orfano per tag script (orphan.getElementsByTagName)
  • ottenere il codice da quei nodi di script (salva per dopo), e poi rimuoverli dal orfano
  • aggiungere il residuo html che si trova in l'orfano e aggiungerlo al segnaposto (placeholder.innerHTML = orphan.innerHTML)
  • creare un elemento di sceneggiatura e aggiungere il codice memorizzato ad esso (scriptElem .text = 'alert ("my code");')
  • quindi aggiungere l'elemento script per il DOM (preferibilmente la testa), quindi rimuoverlo
 
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

Quando si dice che "lavora" in quegli altri browser, vuoi dire che si ottiene il messaggio alert pop-up, o vuoi solo dire che il tag <script> lo fa nell'albero DOM?

Se il tuo obiettivo è il primo, rendi conto che il comportamento di iniettare html con <script> incorporato dipende molto dal browser. Per esempio negli ultimi MooTools posso provare:

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

e faccio non ottenere il pop-up, non in IE (7), non è in FF (3) (però ho fare ottenere il nodo <script> nel DOM con successo). Per ottenerlo a alert in tutti i browser, è necessario fare come fa this answer.

1

Mi dispiace, forse mi manca qualcosa qui - ma essendo questa una domanda di mootools 1.11, perché non usi assets.js?

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

non è uno dei motivi per cui non stiamo usando un quadro di dover reinventare la ruota tutto da capo ...

per quanto riguarda il contenuto di 'altro' è preoccupato , come ti capita di averlo?se attraverso la classe richiesta, si può fare ciò che si vuole bene utilizzando le opzioni:

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

ho incontrato gli stessi problemi con IE8 (e IE7) L'unico modo ho potuto iniettare dinamicamente uno script (con una src) è utilizzando un timer:

source = "bla.js"; 

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

Se si dispone di codice inline che si desidera iniettare, è possibile eliminare il timer e utilizzare il metodo "testo" per l'elemento script:

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

So che la mia risposta è arrivata abbastanza tardi; comunque, meglio tardi che mai :-)

0

E il mio commento è davvero tardivo, ma è anche il più accurato qui - il motivo per cui non vedi il contenuto dello <script> in esecuzione è perché non hai aggiunto l'attributo defer al tag <script>. L'articolo MSDN specifica che è necessario farlo affinché il tag <script> venga eseguito.