Ruby on Rails:允许使用清理助手在代码块内使用小于号“<”
Ruby on Rails: Allow less than sign '<' inside code block with sanitize helper
我正在尝试转义 Rails 中用户生成的内容。我使用 raw 和 sanitize 和 raw 助手来过滤这样的内容:
raw(sanitize(code, :tags => ['<', 'h2','h3','p','br','ul','ol','li','code','pre','a'] ))
允许在内容中提及的标签列表。
问题是当我尝试使用这样的 sql 查询来测试它时:
mysql -u sat -p -h localhost database < data.sql
在 pre 和 code 块中删除小于号 (<) 后的所有内容。
请帮我想想办法。
Rails 3 为每个 String 实例添加了 html_safe
属性。除非 html_safe
设置为 true(简化),否则打印或插入数据库的每个字符串都将被转义。 raw
所做的,实际上是将 html_safe
设置为 true
。所以你应该只传递一个已经是 safe/escaped.
的字符串
可能的解决方案如下所示:
strip_tags(code).html_safe
您可能需要根据您的用例添加额外的检查/字符串替换。
根据您的评论,您可能需要更复杂的版本。您可以尝试替换您希望允许的所有字符,清理字符串,然后反转替换以避免清理方法清理的次数超出您的实际需要。尝试这样的事情:
code = "mysql -u sat -p -h localhost database < data.sql"
ALLOWED_SIGNS = {
:lower_than => "<".html_safe
}
s = code.dup
ALLOWED_SIGNS.each { |k, v| s.sub!(v, "%{#{k}}") }
sanitize(s) % ALLOWED_SIGNS
这可能会有所帮助,消毒剂可以选择提供在消毒过程中需要忽略的标签和属性的白名单
ActionView::Base.full_sanitizer.sanitize(html_string) #Basic Syntax
标签和属性的白名单可以如下指定
ActionView::Base.full_sanitizer.sanitize(html_string, :tags => %w(img br p), :attributes => %w(src style))
以上语句允许标签:img、br 和 p 以及属性:src 和 style。
我认为使用 Rails 中的默认清理方法是不可能的。
改为尝试使用清理 gem (https://github.com/rgrove/sanitize)
require 'sanitize'
allowed_elements = ['h2','h3','p','br','ul','ol','li','code','pre','a']
code = "<pre>mysql -u sat -p -h localhost database < data.sql</pre>"
Sanitize.fragment(code, elements: allowed_elements)
# => <pre>mysql -u sat -p -h localhost database < data.sql</pre>
要使用它来将经过清理的内容保存到数据库中,请向您的模型添加一个 before_save
过滤器,该过滤器对用户生成的内容运行清理并存储结果,例如
class MyModel < ActiveRecord::Base
ALLOWED_ELEMENTS = ['h2','h3','p','br','ul','ol','li','code','pre','a']
before_save :sanitize_code
private
def sanitize_code
self.code = Sanitize.fragment(code, elements: ALLOWED_ELEMENTS)
end
end
当您输出内容时,您只需要使用原始视图助手,例如
<%= raw @instance.code %>
似乎整个问题都与数据在数据库中的存储方式有关。以前,一个小于号 '<' 被按原样保存,但现在它被转义,所以 '<' 将被保存为 <
这似乎已经解决了问题。
我在使用 tinymce-rails 所见即所得编辑器时意外地理解了这一点,该编辑器会自动转义“<”。
@kieran-johnson 的回答可能会做同样的事情,但 tinymce-rails 解决了它而没有安装额外的 gem.
感谢所有抽出时间提供帮助的人。
nokogiri gem 解决问题:
gem 'nokogiri'
Nokogiri::HTML::DocumentFragment.parse('<b>hi</b> x > 5').text
=> "hi x > 5"
考虑通过清理方法在 运行 之前用其 ASCII 字符 <
替换“<”。它应该被转换成 <
然后呈现为“<”字符,而不是 html.
我正在尝试转义 Rails 中用户生成的内容。我使用 raw 和 sanitize 和 raw 助手来过滤这样的内容:
raw(sanitize(code, :tags => ['<', 'h2','h3','p','br','ul','ol','li','code','pre','a'] ))
允许在内容中提及的标签列表。
问题是当我尝试使用这样的 sql 查询来测试它时:
mysql -u sat -p -h localhost database < data.sql
在 pre 和 code 块中删除小于号 (<) 后的所有内容。
请帮我想想办法。
Rails 3 为每个 String 实例添加了 html_safe
属性。除非 html_safe
设置为 true(简化),否则打印或插入数据库的每个字符串都将被转义。 raw
所做的,实际上是将 html_safe
设置为 true
。所以你应该只传递一个已经是 safe/escaped.
可能的解决方案如下所示:
strip_tags(code).html_safe
您可能需要根据您的用例添加额外的检查/字符串替换。
根据您的评论,您可能需要更复杂的版本。您可以尝试替换您希望允许的所有字符,清理字符串,然后反转替换以避免清理方法清理的次数超出您的实际需要。尝试这样的事情:
code = "mysql -u sat -p -h localhost database < data.sql"
ALLOWED_SIGNS = {
:lower_than => "<".html_safe
}
s = code.dup
ALLOWED_SIGNS.each { |k, v| s.sub!(v, "%{#{k}}") }
sanitize(s) % ALLOWED_SIGNS
这可能会有所帮助,消毒剂可以选择提供在消毒过程中需要忽略的标签和属性的白名单
ActionView::Base.full_sanitizer.sanitize(html_string) #Basic Syntax
标签和属性的白名单可以如下指定
ActionView::Base.full_sanitizer.sanitize(html_string, :tags => %w(img br p), :attributes => %w(src style))
以上语句允许标签:img、br 和 p 以及属性:src 和 style。
我认为使用 Rails 中的默认清理方法是不可能的。
改为尝试使用清理 gem (https://github.com/rgrove/sanitize)
require 'sanitize'
allowed_elements = ['h2','h3','p','br','ul','ol','li','code','pre','a']
code = "<pre>mysql -u sat -p -h localhost database < data.sql</pre>"
Sanitize.fragment(code, elements: allowed_elements)
# => <pre>mysql -u sat -p -h localhost database < data.sql</pre>
要使用它来将经过清理的内容保存到数据库中,请向您的模型添加一个 before_save
过滤器,该过滤器对用户生成的内容运行清理并存储结果,例如
class MyModel < ActiveRecord::Base
ALLOWED_ELEMENTS = ['h2','h3','p','br','ul','ol','li','code','pre','a']
before_save :sanitize_code
private
def sanitize_code
self.code = Sanitize.fragment(code, elements: ALLOWED_ELEMENTS)
end
end
当您输出内容时,您只需要使用原始视图助手,例如
<%= raw @instance.code %>
似乎整个问题都与数据在数据库中的存储方式有关。以前,一个小于号 '<' 被按原样保存,但现在它被转义,所以 '<' 将被保存为 <
这似乎已经解决了问题。
我在使用 tinymce-rails 所见即所得编辑器时意外地理解了这一点,该编辑器会自动转义“<”。
@kieran-johnson 的回答可能会做同样的事情,但 tinymce-rails 解决了它而没有安装额外的 gem.
感谢所有抽出时间提供帮助的人。
nokogiri gem 解决问题:
gem 'nokogiri'
Nokogiri::HTML::DocumentFragment.parse('<b>hi</b> x > 5').text
=> "hi x > 5"
考虑通过清理方法在 运行 之前用其 ASCII 字符 <
替换“<”。它应该被转换成 <
然后呈现为“<”字符,而不是 html.