我正在将一个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()创建的标记,或者如果我能够执行,我做错了什么!
答案 0 :(得分:0)
注入的脚本永远不会被执行。这是设计的。你无能为力。
只有两种方法可以将javascript注入页面:
通过HTTP加载。是的,您可以使用createElement()
创建脚本标记,但只有在使用src
属性通过HTTP从文件加载脚本时,它才有效。手动更改脚本标记的内容很久以前就被认为是一个安全问题,自从Netscape Navigator上最初的javascript实现以来,没有任何浏览器允许这样做。
使用eval()
。是的,eval是邪恶的,但它允许你执行eval(script.innerHTML)
来执行脚本标记的内容。我的建议是,如果您发现自己需要eval,那么现在是时候重新评估您尝试做的事情并重新考虑您的架构。
答案 1 :(得分:-2)
这个判决
if (nodeScriptIs(node) === true)
始终返回false
。