2011-01-11 64 views
1

我有这样的事情:的Rails:的link_to方法

<p> 
    <b>Tags:</b> 
    <%if @post.tags.count > 0%> 
    <%= @post.tags.collect {|c| (link_to c.name, c)}.join(", ")%> 
    <%else%> 
    Does not have any tags. 
    <%end%> 
</p> 

这给了我

Tags: <a href="/tags/1">Java</a>, <a href="/tags/2">CSS</a> 

而不是Java和CSS链接。我错过了什么?

回答

6

这是因为Rails 3中的字符串是默认,不被认为是HTML安全的。关于它,请参阅this blog post

也可以手动标记通过调用其.html_safe是安全的东西,这将使你的代码如下所示:

<p> 
    <b>Tags:</b> 
    <%if @post.tags.count > 0%> 
    <%= @post.tags.collect {|c| (link_to c.name, c)}.join(", ").html_safe %> 
    <%else%> 
    Does not have any tags. 
    <%end%> 
</p> 

但我建议这个不要做:

<p> 
    <b>Tags:</b> 
    <% if @post.tags.count > 0%> 
    <% @post.tags.each_with_index do |tag, i| %> 
     <%= link_to h(tag.name), tag %><%= ', ' if i < @post.tags.size - 1 %> 
    <% end %> 
    <% else %> 
    Does not have any tags. 
    <%end%> 
</p> 
3

我认为html_safe是你正在寻找的!所以这将解决问题(@ post.tags.collect {| c |(link_to c.name,c)}。join(“,”))。html_safe

1

我想你的标签名称应该由用户输入,对吧?

在这种情况下,html_safe不是您的首选,因为它给予用户完全信任。你的网站会遇到XSS攻击。

更好的选择应该是sanitize。看到这里的参考:http://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html

因为你只希望有链接,下面这行做你想要什么:

<%= sanitize @post.tags.collect {|c| (link_to strip_links(c.name), c)}.join(", "), :tags => %w(a) %> 

注意使用strip_links(c.name),这将删除所有的链接,由用户输入。

假设的标签名称是: “产品”, “”, “再见”]

只要使用.html_safe,下面会显示:

<a href="/tags/1">Product</a>, <a href="/tags/2"><strong>hi</strong></a>, <a href="/tags/3"><a href='bad_site.com'>bye</a></a> 

但使用与strip_links sanitize方法的组合,以下是结果:

<a href="/tags/1">Product</a>, <a href="/tags/2">&lt;strong&gt;hi&lt;/strong&gt;</a>, <a href="/tags/3">bye</a> 

或者你可以用.html_safe混合使用的strip_tags

<%= @post.tags.collect {|c| (link_to strip_tags(c.name), c)}.join(", ").html_safe %> 

调用html_safe之前,这仅仅去除了c.name所有标签。

我建议(你可能已经在做:D)在存入数据库之前删除所有不需要的标记。

+0

在将用户输入放入数据库之前,我实际上会建议_not_剥离标签。你怎么知道这将显示在哪里?也许它会通过HTML发送,但也可能会通过JSON API发送并显示在iPhone应用程序中。每个显示介质都有独特的安全考虑因素,您存储数据的时间点并不是您可能使用该数据所做的所有事情的时间。 – 2011-01-11 19:24:42