使用jsoup来转义不允许的标记

时间:2012-02-20 16:24:13

标签: java html jsoup xss htmlcleaner

我正在评估jsoup用于清理(但不删除!)非白名单标签的功能。假设只允许<b>标记,所以输入

foo <b>bar</b> <script onLoad='stealYourCookies();'>baz</script>

必须提供以下内容:

foo <b>bar</b> &lt;script onLoad='stealYourCookies();'&gt;baz&lt;/script&gt;

我在jsoup中看到以下问题/问题:

  • document.getAllElements()始终采用<html><head><body>。是的,我可以致电document.body().getAllElements(),但重点是我不知道我的来源是完整的HTML文档还是仅仅是正文 - 我希望结果的形状和形式与它相同;
  • 如何将<script>...</script>替换为&lt;script&gt;...&lt;/script&gt;?我只想用转义的实体替换括号,并且不想改变任何属性等。Node.replaceWith听起来像是一种矫枉过正。
  • 是否可以完全关闭漂亮的打印(例如插入新行等)?

或许我应该使用另一个框架?到目前为止,我已经查看了htmlcleaner,但是给出的示例并未表明我支持所需的功能。

1 个答案:

答案 0 :(得分:5)

答案1

如何使用Jsoup加载/解析Document?如果您使用parse()connect().get(),jsoup会自动格式化您的html(插入htmlbodyhead标记。这个确保你总是有一个完整的Html文档 - 即使输入不完整。

假设您只想清理输入(无需处理),您应该使用clean()而不是之前列出的方法。

示例1 - 使用解析()

final String html = "<b>a</b>";

System.out.println(Jsoup.parse(html));

<强>输出:

<html>
 <head></head>
 <body>
  <b>a</b>
 </body>
</html>

输入html已完成,以确保您拥有完整的文档。

示例2 - 使用clean()

final String html = "<b>a</b>";

System.out.println(Jsoup.clean("<b>a</b>", Whitelist.relaxed()));

<强>输出:

<b>a</b>

输入html已清除,而不是更多。

<强>文档


答案2

方法replaceWith()完全符合您的需要:

示例:

final String html = "<b><script>your script here</script></b>";
Document doc = Jsoup.parse(html);

for( Element element : doc.select("script") )
{
    element.replaceWith(TextNode.createFromEncoded(element.toString(), null));
}

System.out.println(doc);

<强>输出:

<html>
 <head></head>
 <body>
  <b>&lt;script&gt;your script here&lt;/script&gt;</b>
 </body>
</html>

仅限身体

System.out.println(doc.body().html());

<强>输出:

<b>&lt;script&gt;your script here&lt;/script&gt;</b>

<强>文档


答案3

是的,prettyPrint()的{​​{1}}方法可以做到这一点。

示例:

Jsoup.OutputSettings

注意:如果final String html = "<p>your html here</p>"; Document doc = Jsoup.parse(html); doc.outputSettings().prettyPrint(false); System.out.println(doc); 方法不可用,请更新Jsoup。

<强>输出:

outputSettings()

<强>文档


回答4 (无子弹)

不! Jsoup是最佳最强大的 Html库之一!