【问题标题】:How to use nsIParserUtils inside firefox addon sdk 1.10 main.js?如何在 firefox addon sdk 1.10 main.js 中使用 nsIParserUtils?
【发布时间】:2012-10-06 07:15:36
【问题描述】:

我最近提交的 Firefox 插件网站(基于 Firefox 插件 SDK 1.10)被拒绝了,因为我没有对我使用的输入进行清理,并被推荐给use nsIParserUtils

我在该页面中找到了函数parseHTML(doc, html, allowStyle, baseURI, isXML)。我把它改成:

function parseHTML(doc, html, allowStyle, baseURI, isXML) {
    var parser = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils);
    var f =  parser.parseFragment(html, allowStyle ? parser.SanitizerAllowStyle : 0,
                                        !!isXML, baseURI, doc);
    return f;
}

其中的第一个参数被称为文档元素。我不知道那应该是什么?我尝试了document.createDocumentFragment(),但出现“ReferenceError:文档未定义”错误。有人可以帮助我如何调用此函数吗?

该函数返回一个nsIDOMDocumentFragment。如何将其转换回字符串?


更新:

按照@zer0 的建议,我使用了:

var parser = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils);
var sanitizedHTML = parser.sanitize(html, flags);

但这违背了我想做的事情的目的。例如:

<html><head><BASE href='http://localhost/t/h.html' />
<link rel="stylesheet" type="text/css" href="h.css">
<style type="text/css">
.b{
    color:green;
}
</style>
<base href="http://foo.example.com/">
</head><body>Sample Text. No Style
<script>Hello malicious code</script>
<p class="a">External Style</p>
<p class="b">Internal Style</p>
<p style="color:blue">Inline Style</p>

<a href="sample.html">Link</a><br><br><div style='color: #666666; font-size: 12px'>Clipped on 6-October-2012, 07:37:39 PM from <a href='http://localhost/t/h.html'>http://localhost/t/h.html</a> </div></body></html>

转换为:

<html><head>  


<style type="text/css">
.b{

    color:green;
}
</style>



</head><body>Sample Text. No Style

<p class="a">External Style</p>
<p class="b">Internal Style</p>
<p style="color:blue">Inline Style</p>

<a>Link</a><br><br><div style="color: #666666; font-size: 12px">Clipped on 6-October-2012, 07:37:39 PM from <a href="http://localhost/t/h.html">http://localhost/t/h.html</a> </div></body></html>

由于这剥离了外部超链接和 CSS,它违背了插件本身的目的。我想要的只是删除脚本:

<html><head><BASE href='http://localhost/t/h.html' /> <BASE href='http://localhost/t/h.html' /> 
<link rel="stylesheet" type="text/css" href="h.css">

<style type="text/css">
.b{

    color:green;
}
</style>
<base href="http://foo.example.com/">


</head><body>Sample Text. No Style
<p class="a">External Style</p>
<p class="b">Internal Style</p>
<p style="color:blue">Inline Style</p>

<a href="sample.html">Link</a><br><br><div style='color: #666666; font-size: 12px'>Clipped on 6-October-2012, 07:37:39 PM from <a href='http://localhost/t/h.html'>http://localhost/t/h.html</a> </div></body></html>

有人能解释一下吗?

【问题讨论】:

    标签: javascript dom firefox-addon firefox-addon-sdk


    【解决方案1】:

    删除外部样式的链接是有原因的:无法验证外部样式并且它们可能很危险(特别是,-moz-binding 可用于运行代码)。此外,假设您可以将 HTML 代码放在跟随相对链接不安全的位置(例如 Thunderbird 中的邮件消息)。但是,绝对链接总是可以的。

    您可能想要做的是预处理 HTML 代码以消除这些问题 - 解决相对链接和对外部样式的内联引用。像这样的:

    // Parse the HTML code into a temporary document
    var doc = Cc["@mozilla.org/xmlextras/domparser;1"]
                   .createInstance(Ci.nsIDOMParser)
                   .parseFromString(html, "text/html");
    
    // Make sure all links are absolute
    for (var i = 0; i < doc.links.length; i++)
        doc.links[i].setAttribute("href", doc.links[i].href);
    
    // Make sure all stylesheets are inlined
    var stylesheets = doc.getElementsByTagName("link");
    for (i = 0; i < stylesheets.length; i++)
    {
        try
        {
            var request = new XMLHttpRequest();
            request.open("GET", stylesheets[i].href, false);
            request.send(null);
            var style = doc.createElement("style");
            style.setAttribute("type", "text/css");
            style.textContent = request.responseText;
            stylesheets[i].parentNode.replaceChild(style, stylesheets[i]);
            i--;
        }
        catch (e)
        {
            // Ignore download errors
        }
    }
    
    // Serialize the document into a string again
    html = Cc["@mozilla.org/xmlextras/xmlserializer;1"]
             .createInstance(Ci.nsIDOMSerializer)
             .serializeToString(doc.documentElement);
    
    // Now sanizite the HTML code
    var parser = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils);
    var sanitizedHTML = parser.sanitize(html, parser.SanitizerAllowStyle);
    

    请注意,我使用同步 XMLHttpRequest 来下载样式表内容 - 这样做是为了简单起见,您的最终代码应该使用不会挂起用户界面的异步下载(很可能通过 request 模块)。

    【讨论】:

    • 您好,我在 catch 语句中遇到错误,ReferenceError: XMLHttpRequest is not defined。我尝试使用请求 API (addons.mozilla.org/en-US/developers/docs/sdk/latest/modules/sdk/…) 但这太慢了……而且大多数时候它挂起:(
    • @JayarathinaMadharasan:使用附加 SDK,您应该使用 request 模块。如果您在使用它时遇到问题,那么您应该创建一个新问题 - 通常它既不“慢”也不不稳定。
    • 非常感谢您的指导。我让它根据你的代码工作。特别是把所有链接都指向相对的那个。
    • 哎呀,对不起,我不知道 :(.. 但现在做到了...非常感谢... :)
    【解决方案2】:

    其中的第一个参数被称为文档元素。我不知道那是什么?

    你不需要那个。只需使用nsIParserUtils.sanitize 方法,该方法只需获取一个字符串作为输入,然后将经过清理的版本作为输出返回:

    var parser = Cc["@mozilla.org/parserutils;1"].getService(Ci.nsIParserUtils);
    var sanitizedHTML = parser.sanitize(html, flags);
    

    查看“常量”部分上方的链接,了解您需要在场景中使用哪些标志。

    【讨论】:

    • 供参考:在解析之前确保所有链接都是绝对的,否则解析器会将它们全部删除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多