繁体   English   中英

如何将 javascript 注入 IE 8 上的页面?

[英]How do I inject javascript to a page on IE 8?

假设我有以下标记:

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

有没有办法在 IE 8 上注入 JavaScript 或者它是否安全 model 完全禁止我这样做?

我尝试了 Luca Matteis 的使用建议

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

而不是 MooTools 代码,我得到了相同的结果。 这不是 MooTools 问题。

这篇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注入脚本加载标签来提高安全性并减少跨浏览器的不兼容性。 我知道这可能是不可能的,但值得考虑。

大约一年前,我们就是这样在我们的网站上做的,让它在 IE 中运行。 以下是步骤:

  • 将 HTML 添加到孤立的 DOM 元素
  • 在孤立节点中搜索脚本标签 (orphan.getElementsByTagName)
  • 从那些脚本节点获取代码(保存以备后用),然后将它们从孤儿中删除
  • 添加孤立的 html 剩余部分并将其添加到占位符 (placeholder.innerHTML = orphan.innerHTML)
  • 创建一个脚本元素并将存储的代码添加到其中 (scriptElem.text = 'alert("my code");')
  • 然后将脚本元素添加到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");');

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

如果您有要注入的内联代码,您可以删除计时器并为脚本元素使用“文本”方法:

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

我知道我的答案来得太晚了; 但是,迟到总比没有好:-)

对不起,也许我在这里遗漏了一些东西——但这是一个 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"
});

这难道不是我们使用框架不必重新发明轮子的原因之一吗……

就“其他”内容而言,您是如何获得的? 如果通过请求 class,它可以通过使用选项很好地完成您想要的事情:

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

我不确定 MooTools,但您尝试过 innerHTML 吗?

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

您可能需要评估 script 标签的内容。 这将需要解析以在您的 jsVar 和 eval(whatsBetweenTheScriptTags) 中查找脚本。

由于 IE 默认拒绝插入内容,您必须自己执行它,但您至少可以欺骗 IE 为您进行解析。

只需使用string.replace()将所有<script>标签交换为<textarea class="myScript" style="display:none"> ,保留内容。 然后将结果粘贴到 div 的innerHTML中。

完成后,您可以使用

div.getElementsByTagName("textarea") 

要获取所有文本区域,请遍历它们并查找您的标记 class (在本例中为"myScript" ),以及您关心的eval(textarea.value)(new Function(textarea.value))()

我从来没有尝试过,它只是浮现在我的脑海......你可以试试以下:

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 标记。

当您说它在其他浏览器中“有效”时,您的意思是您会收到alert弹出消息,还是只是意味着<script>标记使其进入 DOM 树?

如果您的目标是前者,请意识到使用嵌入的<script>注入 html 的行为非常依赖于浏览器。 例如在最新的 MooTools 我可以尝试:

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

而且我没有得到弹出窗口,没有在 IE(7) 中,也没有在 FF(3) 中(但是我确实<script>节点成功地放入了 DOM)。 要让它在所有浏览器中发出alert ,您必须按照此答案进行操作。

我的评论真的很晚,但它也是这里最准确的评论 - 您没有看到<script>内容运行的原因是因为您没有将defer属性添加到<script>标记。 MSDN 文章特别指出您需要这样做才能使<script>标记运行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM