我需要在Grails错误消息中显示一些HTML,以标记我无法影响的外部系统的某些内容。它只是一些简单的span标签,带有class =“notranslate”属性。默认情况下,HTML将被转义,因此我禁用了标记中的编解码器,这导致了另一个问题:
现在用户输入的所有内容都将显示在页面的HTML中,这样可以轻松实现XSS ... 我现在的解决方案是仅禁用此页面的HTML编解码器,并使用自定义错误消息,这些消息不包括用户输入的内容,但这对我来说似乎相当笨拙。
我也看到可能有可能摆弄MessageSource,但我不喜欢在Grails的内容中改变很多。我的另一个想法是创建一个自定义过滤器,它只允许我批准的HTML。我也放弃了这个想法,感觉我在错误的抽象层面上处理问题。
任何想法如何解决这个问题?
TL; DR 我需要在标记中包含错误消息的可变部分。
答案 0 :(得分:3)
为了不获取HTML编码的错误消息,可以使用以下内容:
<g:hasErrors bean="${editingInstance}">
<div class="errors">
<g:renderErrors bean="${editingInstance}" codec="none"/>
</div>
</g:hasErrors>
'codec'属性将在ValidationTagLib.groovy中使用:
Closure renderErrors = { attrs, body ->
def renderAs = attrs.remove('as')
if (!renderAs) renderAs = 'list'
if (renderAs == 'list') {
def codec = attrs.codec ?: 'HTML'
if (codec == 'none') codec = ''
[...]
}
[...]
}
答案 1 :(得分:1)
我对taglib包装器有所了解。从这开始:
<g:hasErrors bean="${user}">
<ul>
<g:eachError var="err" bean="${user}">
<li><g:message error="${err}" /></li>
</g:eachError>
</ul>
</g:hasErrors>
然后在messages.properties中创建带有一些特殊通配符的消息,如下所示:
user.username.size.toosmall=Username you provided @@@{0}@@@ is too small.
三个&符号是一个荒野。然后创建一个包裹g:message
的taglib,如下所示:
class MyTagLib {
def spanErrorMessage = { attrs, body ->
out << message(error: attrs.error).replaceAll(/@@@.*@@@/, "<span class='notranslate'>\\1</span>")
}
}
它会将@@@
和@@@
之间的所有内容替换为您需要的范围。请注意,这些@@@
不会在HTML中转义。像这样使用这个taglib:
<g:hasErrors bean="${user}">
<ul>
<g:eachError var="err" bean="${user}">
<li><g:spanErrorMessage error="${err}" /></li>
</g:eachError>
</ul>
</g:hasErrors>
此代码未经测试,从头开始,因此它可能会错过正则表达式中的一些细节,但我希望您能理解。