即使脚本标签“已修复”

时间:2017-12-04 01:38:26

标签: javascript html dom iwebbrowser2

我正在将一个DIV和一些SCRIPT注入到加载到我的IWebBrowser2控件中的文档的DOM中。我无法再执行脚本,因为当以这种方式注入时,它们不是“真正的”脚本标记。

我在这里用不同的问题找到了解决方案,或者我想到了。提供的编码(下面)似乎有效 - 它用所有通过调用createElement()创建的真实脚本元素替换所有注入的文本标签。

<script>
    function nodeScriptReplace(node)
    {
        if (nodeScriptIs(node) === true)
        {
            alert("Fixing " + node.id);
            node.parentNode.replaceChild(nodeScriptClone(node), node);
        }
        else
        {
            var i = 0;
            var children = node.childNodes;
            while (i < children.length)
            {
                nodeScriptReplace(children[i++]);
            }
        }
        return node;
    }
    function nodeScriptIs(node)
    {
        return node.tagName === 'SCRIPT';
    }
    function nodeScriptClone(node)
    {
        var script = document.createElement("script");
        script.text = node.innerHTML;
        for (var i = node.attributes.length - 1; i >= 0; i--)
        {
            script.setAttribute(node.attributes[i].name, node.attributes[i].value);
        }
        return script;
    }
    function FixAllScripts()
    {
        nodeScriptReplace(document.getElementsByTagName("body")[0]);
        return true;
    }
</script>

我已经确认它确实如此,但是当我通过IWebBrowser2控件尝试使用ExecuteScript()时,它不起作用。如果我将脚本移动到原始页面而不是注入的块,我已经验证了它 - 工作。但我需要它来执行注入的块。

注入的块看起来像这样:

<table cellpadding="0" cellspacing="0" style="background-color: white;">
...etc'
</table>
<br />

<script id="SayHi">
    function SayHi() {
        alert("Hi!");
        return 5;
    }
</script>

在我托管控件的代码中,我执行以下操作:

        var el = mainBrowser.Document.GetElementById("InsertionPoint");
        el.InnerHtml = toInsert + el.InnerHtml + "<BR/>";

        var bar = mainBrowser.Document.InvokeScript("FixAllScripts");
        var foo = mainBrowser.Document.InvokeScript("SayHi");

所以我注入我的HTML并在原始页面中运行“FixAllScripts”脚本,该脚本应该修复“SayHi”脚本。

我已经验证了我注入的标签被reaplceChild检测到并“修复”了。然而执行它们什么也没做。

最终的问题是为什么我不能执行使用createElement()创建的标记,或者如果我能够执行,我做错了什么!

2 个答案:

答案 0 :(得分:0)

注入的脚本永远不会被执行。这是设计的。你无能为力。

只有两种方法可以将javascript注入页面:

  1. 通过HTTP加载。是的,您可以使用createElement()创建脚本标记,但只有在使用src属性通过HTTP从文件加载脚本时,它才有效。手动更改脚本标记的内容很久以前就被认为是一个安全问题,自从Netscape Navigator上最初的javascript实现以来,没有任何浏览器允许这样做。

  2. 使用eval()。是的,eval是邪恶的,但它允许你执行eval(script.innerHTML)来执行脚本标记的内容。我的建议是,如果您发现自己需要eval,那么现在是时候重新评估您尝试做的事情并重新考虑您的架构。

答案 1 :(得分:-2)

这个判决

if (nodeScriptIs(node) === true)

始终返回false