我正在将DIV和一些脚本注入加载到我的iwebbrowser2控件中的文档中。然后我无法执行脚本,因为当以这种方式注入时,它们不是"真实"的脚本标签。
我在这里找到了解决方案,或者我想到了一个不同的问题。所提供的编码(下)似乎可以使用 - 它替换了所有注入的文本标签,其中用呼叫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控件上执行()()时,它不起作用。如果我将脚本移至原始页面而不是注入的块,则我已经对其进行了验证。但是我需要它执行注射块。
注入的块看起来像这样:
<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并在原始页面中运行" fixallscript"脚本,该脚本应该修复" sayhi"脚本。
我已经验证了已检测到的标签,并由Reaplcechild"修复"。然而执行它们什么也没做。
最终的问题是为什么我不能执行使用CreateElement()创建的标签,或者如果我应该能够,我做错了什么!
注入的脚本永远不会被执行。这是设计。您无能为力。
只有两种方法可以将JavaScript注入页面:
-
通过HTTP加载它。是的,您可以使用
createElement()
创建一个脚本标签,但是仅当您使用src
属性通过HTTP加载脚本时,它才能起作用。自从Netscape Navigator上的JavaScript实现以来 -
使用
eval()
。是的,评估是邪恶的,但它确实允许您执行eval(script.innerHTML)
执行脚本标签的内容。我的建议是,如果您发现自己需要评估,那么是时候重新评估您要做的事情并重新考虑您的体系结构了。
此判断
if (nodeScriptIs(node) === true)
总是返回false
。