Rails HTML 允许消毒剂没有按我预期的那样工作

Rails HTML Permit Sanitizer Not Working As I Expected

我一直在想弄清楚如何使用 Rails 消毒剂。它似乎没有像我预期的那样工作。我想我误会了什么。

基本上,我正在尝试清理除 divs 之外的所有 divs,这些 divs 的属性值为 highlight。但是为了举例,我尝试单独使用 PermitScrubber

我设置了我的标签和属性并继承自 PermitScrubber,但它无论如何都会清除我允许的标签和属性:

class ExampleScrubber < Rails::Html::PermitScrubber
  def initialize
    super
    self.tags = %w(img),
    self.attributes = %w(src alt)
  end

  # commented out for the example, but what I'm trying to ultimately do
  # def allowed_node?(node)
    # node.name == "div" && node.attributes.values.first.value = "highlight"
  # end
end

@comment.body = "<ul>\n<li>yes</li>\n<li>tests</li>\n</ul>\n\n<p><img src=\"something.jpeg\" alt=\"something\"></p>\n"
ActionController::Base.helpers.sanitize(
  @comment.body,
  scrubber: ExampleScrubber.new
)
#=> "\nyes\ntests\n\n\n\n"

所以有两件事: 1. 为什么要擦除img 标签和srcalt 属性? 2. 我知道我可以重构 allowed_node? 方法,但我想先找出第一个。

感谢阅读✌️

第一个问题("Why is [this] scrubbing the img tag and src and alt attributes?")是由数组后面的杂散逗号引起的。

#             Here v
self.tags = %w(img),

TIL Ruby 不需要数组的方括号:

a = "b", "c" # => ["b", "c"]

所以,那个逗号将你的 tags 变成了一个数组:

ExampleScrubber.new.tags # => [["img"], ["src", "alt"]]

这导致了问题并允许擦除标签。删除逗号会使事情正常工作:

class ExampleScrubber < Rails::Html::PermitScrubber
  def initialize
    super
    self.tags = %w(img)
    self.attributes = %w(src alt)
  end

  # commented out for the example, but what I'm trying to ultimately do
  # def allowed_node?(node)
    # node.name == "div" && node.attributes.values.first.value = "highlight"
  # end
end

body = "<ul>\n<li>yes</li>\n<li>tests</li>\n</ul>\n\n<p><img src=\"something.jpeg\" alt=\"something\"></p>\n"
ActionController::Base.helpers.sanitize(body, scrubber: ExampleScrubber.new)
# => "\nyes\ntests\n\n\n<img src=\"something.jpeg\" alt=\"something\">\n"

因此,为了实现您的目标,只保留 divs 并且只有当它们具有包含单词 'highlight' 的属性(任何属性)时,您可以尝试类似的方法:

class ExampleScrubber < Rails::Html::PermitScrubber
  def initialize
    super
    self.tags = %w( div )
  end

  def allowed_node?(node)
    @tags.include?(node.name) && node.attributes.values.any? do |attribute_value|
      attribute_value.value.include?('highlight')
    end
  end
end

body = "<ul>\n<li class='highlight'>yes</li>\n<li>tests</li>\n</ul>\n\n<p><img src=\"something.jpeg\" alt=\"something\"></p>\n<div class='highlight'>Something</div><div>Else</div>"
results = ActionController::Base.helpers.sanitize(body, scrubber: ExampleScrubber.new)
# => "\nyes\ntests\n\n\n\n<div class=\"highlight\">Something</div>Else"