我有这个从服务器获取html部分的javascript。我能够在警告消息中返回html,这是正确的代码。
ajax: function(url){
var request = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Components.interfaces.nsIXMLHttpRequest);
request.onreadystatechange = function() {
if (request.readyState == 4) {
// only if "OK"
if (request.status == 200) {
var popup = document.getElementById("ajax"); // a <menupopup> element
var txt = request.responseText;
alert(txt);
popup.appendChild(txt);
} else {
alert("There was a problem retrieving the XML data:\n" +
request.statusText);
}
}
};
request.open("GET", url, true);
request.send(null);
}
从服务器返回的xul / html:
<menuitem>
<html:h2><html:a href="http://google.com">Google</html:a></html:h2>
<html:p><html:table><html:tr><html:td>xxxx</html:td></html:tr></html:table></html:p>
</menuitem>
<menuitem>
<html:h2><html:a href="http://yahoo.com">Yahoo</html:a></html:h2>
<html:p><html:table><html:tr><html:td>yyyy</html:td></html:tr></html:table></html:p>
</menuitem>
我的xul页面:
......更多代码
<menu class="menu" label="test">
<menupopup id="ajax" width="450" height="700" onpopupshowing="myextension.ajax('http://www.myserver.com/phpscript.php'>
</menupopup>
</menu>
现在,如果我将html直接附加到带有id ajax的menupopup,它会按预期工作。当我使用appendChild附加它时,它没有。我知道我不能使用appendChild但是在XUL中似乎没有相当于innerHTML的东西。我无法控制从服务器返回的xul / html,因此我无法使用DOM方法添加内容并绕过html。
我尝试使用HTMLParser https://developer.mozilla.org/en/Code_snippets/HTML_to_DOM将其转换为DOM对象,但这似乎不起作用,我相信因为它会删除<menuitem>
标记。
有关如何将HTML附加到menupopup的任何想法,以便我可以将它们显示为菜单项。
好的我尝试了iframe方法:
ajax: function(url){
var request = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Components.interfaces.nsIXMLHttpRequest);
request.onreadystatechange = function() {
if (request.readyState == 4) {
// only if "OK"
if (request.status == 200) {
var frame = document.getElementById("frame");
frame.setAttribute("src", "data:text/html," + encodeURIComponent(request.responseText));
} else {
alert("There was a problem retrieving the XML data:\n" + request.statusText);
}
}
};
request.open("GET", url, true);
request.send(null);
}
带
<iframe id="frame" type="content" src="" />
这似乎不起作用。但是,如果我对encodeURIComponent(request.responseText)发出警报,它就会被正确编码。如果我直接将它添加到iframe中,就更好了:
<iframe type="content" src="data:text/html,%3Chtml%3E%0A%3Cbody%3E%0A%3Cp%3EHello%20everyone%3C%2Fp%3E%0A%09%3C%2Fbody%3E%0A%3C%2Fhtml%3E%0A%0A"/>
它不起作用,因为要显示它需要在标签内的html,但html包含许多不同的项目,每个项目都应该在它们自己的标签中。简单地添加到html是行不通的。
答案 0 :(得分:3)
首先是正确答案,这不是你想要的,但重要的是省略:
请勿将远程检索的HTML或javascript代码附加/注入/放入XUL或Chrome代码范围内!
这样的东西总是一个安全漏洞。 JS是可执行的,HTML也可以包含可执行位(例如javascript:protocol)。任何注入的代码都将以完全浏览器权限运行,这转换为操作系统用户权限(在Windows XP上转换为管理员权限)。
你需要转义html,或解析它,只留下安全位。
您无法信任远程代码,即使它来自您自己的服务器:
顺便说一句:将上传/注入/任何远程检索的代码或HTML放入chrome空间将导致在addons.mozilla.org上拒绝受影响的加载项版本,原因如上所述。
现在是技术上正确的答案,但不要使用远程检索和清理的HTML:
xmlns:html="http://www.w3.org/1999/xhtml"
)appendElement()
文本,而只能是真正的DOM元素。因此,您必须先将任何文本解析为DOM。使用有效的XML(DOMParser)最简单;可以通过隐藏的iframe标记汤的东西。adoptNode
来自不同DOM的任何元素答案 1 :(得分:1)
您的代码确实是一个安全漏洞,您永远不应该这样做。然而,有一种相对简单的方法可以安全地执行它(重要的是:假设您的XUL未在浏览器的内容区域中运行)。你把一个iframe放到你的menupopup中:
<menu class="menu" label="test">
<menupopup id="ajax" onpopupshowing="myextension.ajax('http://www.myserver.com/phpscript.php'>
<menuitem>
<iframe id="frame" type="content" width="450" height="700"></iframe>
</menuitem>
</menupopup>
</menu>
然后,您可以使用data:URL将数据加载到该框架中。这里的重要部分是type =“content”,这会在您的代码(chrome)和您加载的代码(内容)之间创建一个安全边界。这就是为什么你的XUL文档不在浏览器的内容区域中很重要 - 那么你已经在安全边界的“内容”一侧,你不能建立另一个。
实际上将数据放入框架中的方式如下:
var frame = document.getElementById("frame"); // <iframe> element
var txt = request.responseText;
frame.setAttribute("src", "data:text/html;charset=utf-8," + encodeURIComponent(txt));
有关详细信息,请参阅https://developer.mozilla.org/En/Displaying_web_content_in_an_extension_without_security_issues(本文专门针对RSS阅读器编写)。