2011-11-04 112 views
5

Grails的XSS防护功能也很方便保存新的生产线,所以我启用它使用:在使用Grails中的HTML编码解码器观看

grails.views.default.codec = "html" 

虽然,这将创建HTML textareas问题。如果我们完成一个textarea并使用Enter断开线条,则新线条将保存在数据库中,但它们在视图中将被忽略。我可以使用<%=%>replaceAll('\n',"<br>")修复换行符,但填入textarea的HTML代码不会被转义,并且不会有XSS预防!

你将如何解决这个问题?

回答

10

渲染你的textarea早在GSP之前,你可以

  • 编码的字符串作为HTML
  • 换行字符转换为<br/>

这可以通过保存下列标记库到的grails-app /标签库来实现:

class LinesTagLib { 
    def lines = { attrs, body -> 
    out << attrs['string'].encodeAsHTML().replace('\n', '<br/>\n') 
    } 
} 

正如我们已经在标签应用encodeAsHTML(),您必须禁用HTML编解码器使用时,标签(使用<%=expression%>代替${expression}):

<g:lines string="<%=savedTextarea%>" /> 

另一种方法是,以写自己的编解码器为:

class HTMLLinesCodec{ 
    static encode = { str -> 
    str.encodeAsHTML().replace('\n', '<br/>\n') 
    } 
} 

然后,您可以使用此编解码器,你加入指令希望这种行为GSP文件:

<%@ defaultCodec="HTMLLines" %> 
+1

嘿安东尼,感谢您的回复。我想出了一个中介解决方案。你怎么说保留引用为“html”,但处理我的textareas:<%= book?.description?.encodeAsHTML()。replaceAll('\ n','
')%>。你看到这个解决方案的缺点吗? – Pomario

+1

您的解决方案看起来不错。我不喜欢在我的GSP中到处都有这样复杂的声明,这就是为什么我会使用TagLib。如果稍后您决定要在'

字符串

'中附加行,则只需更改TagLib。但是你是对的,如果你只在一个地方使用它,那么使用'<%= book?.description?.encodeAsHTML()。replaceAll('\ n','
')%>'可能是最快的解决方案。 – Antoine

+0

我不得不将静态defaultEncodeAs ='raw'添加到LinesTagLib中,并像(Grails 2.3.6) – CoPLaS