所见即所得 gem 的 "html_safe" 方法不起作用

wysiwyg gem's "html_safe" method doesn't work

我正在写博客,作为一种形式,我使用 wysiwyg gem of froala editor。我还缩短了索引页上的 post 内容,我使用 truncate 方法。问题是 .html_safe 方法(应该显示来自编辑表单的内容不是 html 代码而是纯文本)不能与 truncate 方法串联使用。所以,这是代码:

index.html.erb

<% @posts.each do |post| %>
    <h3 class="title">
        <%= post.title %>
        <small class="date">
            | <%= post.created_at.strftime('%B, %d, %Y') %>
        </small>
   </h3>
   <p class="fr-view">
       <%= truncate(post.content, length: 100).html_safe %>...
       <%= link_to ' Read more', post %>
   </p>
<% end %>

_form.html.erb

<%= form_for @post, role:"form" do |f| %>
    <p>
        <%= f.label :title %><br>
        <%= f.text_field :title %>
    </p>
    <div class="form-group">
        <%= f.label :content %><br>
        <%= f.text_area :content, id:"edit", rows:"3", class:"form-control" %>
    </div>
    <p>
        <%= f.submit 'Create', class:'btn btn-primary' %>
    </p>
<% end %>
<script>
  $(function() {
    $('#edit').froalaEditor()
  });
</script>

控制台中 post.content 的 returns 就是这样:

Post.find(1)
     <Post id: 1, title: "Lorem Ipsum", content: "<p>Lorem ipsum dolor sit amet, consectetur adipisc..."

问题是你把顺序弄反了。 html_safe 将一个字符串标记为受信任的,但是如果您随后对其进行其他操作,它就不再受信任了。这应该有效:

<p class="fr-view">
    <%= truncate(post.content, length: 100).html_safe %>
</p>

更新:在评论中讨论这个问题后,我认为问题是如果你截断,一些标签可能会保持打开状态,这可能会在你的页面中产生各种问题(不一定限于字符串的内容)。几个选项:

  1. 不截断字符串,但用CSS限制显示部分;在这种情况下,您仍然会有有效的 HTML 代码,它应该在浏览器中正确呈现;
  2. 在截断之前删除所有 HTML 标签,如下所示:truncate strip_tags(post.content), length: 100。这也将更加安全,因为您的用户可能会插入恶意代码。

一般来说,在 rails 中使用 sanitize 而不是 html_safe 是一种很好的做法,可以降低将用户输入的恶意代码发送到浏览器的风险。