Как добавить JavaScript на страницу в IE 8? - PullRequest
6 голосов
/ 01 апреля 2009

Предположим, у меня есть следующая разметка:

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

и у меня есть переменная JavaScript jsVar, которая содержит некоторую разметку и немного JavaScript.

Используя Mootools 1.1, я могу вставить содержимое JavaScript в заполнитель следующим образом:

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

Это работает в Firefox, Opera и даже Safari, и итоговая разметка выглядит следующим образом:

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

Однако в IE 8 я получаю следующее:

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

Есть ли способ внедрить JavaScript в IE 8 или модель безопасности вообще запрещает мне это делать?

Я попробовал предложение Луки Маттеиса об использовании

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

вместо кода MooTools и я получаю тот же результат. Это не проблема MooTools.

Ответы [ 10 ]

5 голосов
/ 01 апреля 2009

В этом сообщении MSDN конкретно описывается, как использовать innerHTML для вставки JavaScript на страницу. Вы правы: IE считает это проблемой безопасности, поэтому требует, чтобы вы перепрыгнули через определенные обручи, чтобы ввести скрипт ... предположительно, хакеры могут прочитать этот пост MSDN так же хорошо, как и мы, поэтому я в растерянности почему MS считает этот дополнительный уровень косвенности «безопасным», но я отвлекся.

Из статьи 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>

Если это вообще возможно, вы можете рассмотреть возможность использования тега загрузки встроенного скрипта document.write, чтобы повысить безопасность и уменьшить кросс-браузерную несовместимость. Я понимаю, что это может быть невозможно, но стоит задуматься.

4 голосов
/ 01 апреля 2009

Вот как мы сделали это на нашем сайте около года назад, чтобы заставить его работать в IE. Вот шаги:

  • добавить HTML-код для потерянного элемента DOM
  • поиск в потерянном узле тегов скрипта (orphan.getElementsByTagName)
  • получить код из этих узлов сценария (сохранить на потом), а затем удалить их из сироты
  • добавить остаток html, находящийся в сироте, и добавить его в качестве заполнителя (placeholder.innerHTML = orphan.innerHTML)
  • создать элемент script и добавить в него сохраненный код (scriptElem.text = 'alert ("my code");')
  • затем добавьте элемент script в DOM (желательно в заголовок), затем удалите его
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");');
2 голосов
/ 25 апреля 2011

Я столкнулся с теми же проблемами с IE8 (и IE7) Единственный способ, которым я могу динамически внедрить скрипт (с помощью src), это использовать таймер:

source = "bla.js";

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

Если у вас есть встроенный код, который вы хотите внедрить, вы можете удалить таймер и использовать метод «text» для элемента script:

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

Я знаю, что мой ответ пришел довольно поздно; однако лучше поздно, чем никогда: -)

1 голос
/ 24 июня 2009

Прошу прощения, возможно, я что-то здесь упускаю - но с этим вопросом mootools 1.11, почему вы не используете assets.js?

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

Это не одна из причин, почему мы используем фреймворк , а не , чтобы заново изобретать колесо ...

Что касается «другого» контента, как вы можете его получить? если через класс Request он может делать то, что вы хотите, используя параметры:

{
    update: $("targetId"),
    evalScripts: true,
    evalResponse: false
}
1 голос
/ 01 апреля 2009

Я никогда не пробовал, просто пришло мне в голову ... Можете ли вы попробовать следующее:

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

Вы можете использовать ту же технику (DOM) для вставки разметки HTML.

1 голос
/ 01 апреля 2009

Поскольку IE по умолчанию отказывается вставлять содержимое, вам придется выполнить его самостоятельно, но вы можете, по крайней мере, обмануть IE, выполнив разбор за вас.

Просто используйте string.replace(), чтобы поменять все теги <script> на <textarea class="myScript" style="display:none">, сохранив содержимое. Затем вставьте результат в innerHTML деления.

После этого вы можете использовать

div.getElementsByTagName("textarea") 

, чтобы получить все текстовые поля, прокрутите их и найдите свой класс маркера (в данном случае "myScript"), а также eval(textarea.value) или (new Function(textarea.value))() те, которые вам нужны.

1 голос
/ 01 апреля 2009

Вам может понадобиться проверить содержимое тега скрипта. Это потребует анализа для поиска скриптов в вашем jsVar и eval (whatsBetweenTheScriptTags).

1 голос
/ 01 апреля 2009

Я не уверен насчет MooTools, но вы пробовали innerHTML?

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

0 голосов
/ 14 октября 2011

И мой комментарий действительно запаздывает, но он также самый точный здесь - причина, по которой вы не видите работающего содержимого <script>, заключается в том, что вы не добавили атрибут defer в тег <script> , В статье MSDN специально сказано, что вам нужно сделать это для запуска тега <script>.

0 голосов
/ 02 апреля 2009

Когда вы говорите, что это «работает» в других браузерах, вы имеете в виду, что получаете всплывающее сообщение alert, или вы просто подразумеваете, что тег <script> превращает его в дерево DOM?

Если ваша цель - первая, осознайте, что поведение внедрения html со встроенным <script> очень зависит от браузера. Например, в последних версиях MooTools я могу попробовать:

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

и я не получаю всплывающее окно, не в IE (7), не в FF (3) (однако я do успешно получаю узел <script> в DOM ). Чтобы получить alert во всех браузерах, вы должны сделать этот ответ .

...