3

我想在我的 JSPX 中从一些 JSON(通过 Jackson 生成)初始化一个 Javascript 变量,如下所示:

<script>
var x = <c:out value="${myJson}" />;
</script>

但我得到的输出看起来像:

<script>
var x = {&#034;foo&#034;:&#034bar&#034};
</script>

我看到你在那里做了什么,对字符串进行 HTML 转义。显然,我不能让它完全不转义,因为数据中的尖括号可能会破坏页面。但我真的不需要转义所有引号,因为我没有将 JSON 放在属性值中,对吗?

现在,这似乎是用 HTML 编写脚本的一种完全有效的方法,只是不必要的复杂(例如,用 替换空格&#32;)。事实证明,它在 XHTML 中工作得很好,但是对于 HTML 内容类型,我在 Firefox 和 IE 中都得到一个错误。我不确定其中的原因,但事实就是这样。

那么,这里最好的方法是什么?我真的想简单地转义尖括号而不是转义双引号,还是有其他问题?是否有可以替换的标签c:out(我知道有用于转义 Javascript 的 Spring 标签,但这仍然不是正确的转义方式)?人们如何让它发挥作用?

顺便说一句,是的,我可以进行单独的 AJAX 调用,但是为了解决这个问题而进行额外的往返似乎很愚蠢。

更新

关于 CDATA 与 PCDATA 以及HTML 与 XHTML 有何不同,我需要了解很多。在这里,我认为 JSPX 会使多语言标记变得容易,但事实证明,正如有人所说,它是一大堆讨厌的.

对于 HTML,<script>元素有一个CDATA 内容模型(不要与 CDATA 部分混淆),这意味着没有任何东西可以转义,但</ 必须绝对避免。

在 JSON 的特殊情况下,结束标记只能出现在带引号的字符串中,因此这意味着转义的安全方法是使用 Javascript(而不是 HTML)转义并替换</<\/.

另一方面,对于 XHTML(如果您关心这些事情),您只需像往常一样对所有内容进行 XML 转义(&变成&amp;等),一切都很好。一个兼容的解决方案必须使用 CDATA 并<!--/*--><![CDATA[/*><!--*/在整个<script>正文周围保护注释(等),然后转义]]>JSON 中的任何出现;</而且,为了安全起见,我还是会逃跑。确实很讨厌,但至少它可以自动化。

4

2 回答 2

4

escapeXml=false

<c:out value="${myJson}" escapeXml="false"/>
于 2012-07-21T06:22:42.250 回答
1

好的,经过大量研究并且没有真正的帮助,在这里回答我自己的问题。

基于我上面的“更新”,针对 HTML 最直接的方法就是:

<script>
var x = ${fn:replace(myJson, "\</", "\<\\/")};
</script>

丑陋但简单。

不幸的是,这不会产生有效的 XML 或 XHTML。如果你真的需要它,原件c:out可以正常工作,尽管它不会产生有效的 HTML。如果你真的需要一个解决方案来处理这两个问题,你可能需要一个自定义的 taglib(或 TAGX),它可以从内容类型切换或执行以下所有操作:

  • 将脚本主体包装在注释保护的CDATA 部分中
  • 将每个替换</<\/
  • 将每个替换]]>]]\>
于 2012-07-24T03:06:41.343 回答