Ruby on Rails:使用清理助手在代码块内允许小于号“<”
Posted
技术标签:
【中文标题】Ruby on Rails:使用清理助手在代码块内允许小于号“<”【英文标题】:Ruby on Rails: Allow less than sign '<' inside code block with sanitize helper 【发布时间】:2016-07-22 03:23:13 【问题描述】:我试图在 Rails 中转义用户生成的内容。我使用带有 sanitize 和 raw 助手的 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 块中,它会删除小于 (
请帮我想办法做到这一点。
【问题讨论】:
我无法在控制台中重现您的问题。也许您应该显示您传递给sanitize
的确切内容。此外,“
这一行:“mysql -u sat -p -h localhost database我认为这与数据在数据库中的存储方式有关。您能建议存储和呈现源代码的最佳方式吗? 嗯,渲染是您一直在问的问题,但就存储而言,我不明白您为什么要使用比足够大的字符串类型更复杂的东西。如果您的数据库破坏了您的内容,您应该能够通过前后比较来检测到这一点。 不,不是。这只是渲染问题。我正在使用 raw 和 sanitize 助手: raw(sanitize(code, :tags => ['h2','h3','p','br','blockquote', 'ul','ol','li ','强','代码','pre','a']))。它工作正常,除了遇到' 【参考方案1】:”将只导致:“mysql -u sat -p -h localhost数据库”,并且结束的 pre 标记也被删除。这会导致奇怪的标记。
Rails 3 为每个 String 实例添加了 html_safe
属性。除非 html_safe
设置为 true(简化),否则打印或插入数据库的每个字符串都将被转义。 raw
所做的实际上是将html_safe
设置为true
。所以你应该只传递一个已经安全/转义的字符串。
可能的解决方案如下所示:
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
【讨论】:
问题是我必须清理用户输入,但还允许问题中所述的某些 html 标签。问题是 sanitize 也删除了小于号 ' 我已经更新了我的答案并添加了一些仍然使用sanitize
方法的示例代码。因此,您可以以与您的问题相同的方式添加您允许的 tags
。【参考方案2】:
这可能会有所帮助,sanitizer 可以选择提供在清理期间需要忽略的标签和属性的白名单
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。
【讨论】:
您将如何允许问题中的 mysql 查询中提到的小于“ 在我的一个应用程序中,这就是我允许 img、br、p 元素和 src 、样式属性的方式。由于 ' 如果您注意我的问题描述,这正是我允许标签的方式。如果我可以“尝试一些解决方法”,我就不会在这里问这个问题了。 @IslamWazery 完全正确【参考方案3】:我不相信在 Rails 中使用默认的清理方法是不可能的。
尝试使用 Sanitize 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 %>
【讨论】:
【参考方案4】:似乎整个问题都在于数据在数据库中的存储方式。以前,小于号“<,这似乎解决了问题。
我在使用tinymce-rails WYSIWYG 编辑器时意外地理解了这一点,该编辑器自动转义了“
@kieran-johnson 的回答可能也是如此,但 tinymce-rails 无需安装额外的 gem 即可解决。
感谢所有抽出时间提供帮助的人。
【讨论】:
【参考方案5】:nokogirigem 解决问题:
宝石'nokogiri'
Nokogiri::HTML::DocumentFragment.parse('<b>hi</b> x > 5').text
=> "hi x > 5"
【讨论】:
【参考方案6】:在通过 sanitize 方法运行之前,请考虑将“<。它应该被转换成&lt;
,然后呈现为“
【讨论】:
以上是关于Ruby on Rails:使用清理助手在代码块内允许小于号“<”的主要内容,如果未能解决你的问题,请参考以下文章
如何在 ruby on rails 中访问 rails 助手和嵌入资产 javascript 文件中的 ruby?
Ruby on Rails 使用视图助手中的变量在视图中动态生成字段名称