Rails 3:使用 h(即 html_escape)的助手应该在哪里?
我正在 Ruby on Rails 3 中编写一个 Web 应用程序。Rails 3 会自动转义任何可能有问题的字符串,这通常是一件好事,但意味着如果您自己组装 HTML,则必须调用 html_safe
它。
我有一个卡片模型,它有几个文本字段,其内容不受信任(可能包含邪恶的 HTML 或脚本)。我有一个函数,可以使用有关特定卡片的其他知识对这些文本字段之一执行一些转换,以生成 HTML 输出。我想将此函数生成的 HTML 嵌入到我的应用程序的多个部分的多个位置。
从概念上讲,这个助手与视图有关。但是,我找不到任何方法在我的视图文件中编写函数;看来他们必须进入助手或控制器/模型。
由于此函数非常特定于 Card 对象,因此下一个最佳选择是在我的 Card 模型 card.rb 中包含一个函数:
class Card < ActiveRecord::Base
[...]
def format(unsafe_text)
initial_text = h unsafe_text # aka html_escape unsafe_text
# assembles HTML output based on initial_text and fields of self
output_text.html_safe!
end
然后我想通过执行以下操作在各种视图中调用此函数:
Rules text: <%= format(@card.rulestext) %>
但是,有一个这里也是一个大问题。在卡模型card.rb中,我可以使用html_safe!
函数,但无法使用h
或html_escape
。看来 h
和 html_escape
函数仅在 ERB 视图中可用,而在帮助器或控制器中不可用!
有一些解决方法。我可以使 format
不清理其输入,然后继续
Rules text: <%= format(h(@card.rulestext)) %>
,但这很容易出现危险的失误(缺少一个 h()
,我们就会遇到问题),而且非常不-干燥的。目前我正在使用部分来访问 h()
函数:
(in a normal view)
Rules text: <%= render 'formattext', :text=> @card.rulestext %>
(app/views/shared/_formattext.html.erb)
<%= @card.format(html_escape(text)) %>
但这仍然感觉很危险。我所要做的就是在视图中对 format(sometext)
进行一次忘记调用,而不是调用 render 'formattext', :text=>; sometext
,并且我已经得到了未转义的文本。
有没有更好的方法来做到这一点?有没有办法编写辅助函数来驻留在视图而不是模型或控制器中?
I'm writing a webapp in Ruby on Rails 3. Rails 3 automatically escapes any potentially-bad strings, which is generally a good thing, but means if you assemble HTML yourself, you have to call html_safe
on it.
I have a Card model, which has several text fields, the contents of which are not trusted (may contain evil HTML or script). I have a function which performs a few transforms on one of these text fields, using other knowledge about the specific Card, to produce HTML output. I want to embed the HTML produced by this function in several places throughout several parts of my app.
Conceptually, this helper is to do with the View. However, I can't find any way to write functions in my View files; it seems they have to go in Helpers or the Controller/Model.
Since this function is very much specific to a Card object, the next best option would be to have a function inside my Card model card.rb:
class Card < ActiveRecord::Base
[...]
def format(unsafe_text)
initial_text = h unsafe_text # aka html_escape unsafe_text
# assembles HTML output based on initial_text and fields of self
output_text.html_safe!
end
Then I'd like to call this in assorted views by doing things like:
Rules text: <%= format(@card.rulestext) %>
However, there's a big problem here as well. In the Card model card.rb, I am able to use the html_safe!
function, but I'm not able to use h
or html_escape
. It seems that the h
and html_escape
functions are only available in ERB views, not in the helpers or controllers!
There are a few workarounds. I can make format
not sanitize its input, and go
Rules text: <%= format(h(@card.rulestext)) %>
But that's both prone to dangerous slipups (one missing h()
and we've got problems) and is very non-DRY. At the moment I'm using a partial to gain access to the h()
function:
(in a normal view)
Rules text: <%= render 'formattext', :text=> @card.rulestext %>
(app/views/shared/_formattext.html.erb)
<%= @card.format(html_escape(text)) %>
But this still feels dangerous. All I have to do is make single forgetful call to format(sometext)
in a view, rather than calling render 'formattext', :text=> sometext
, and I've got unescaped text running around.
Is there any better way to do this? Is there a way to write helper functions to live in the View rather than the Model or the Controller?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
将执行视图组装的逻辑放入 CardHelper 中:
app/helpers/card_helper.rb
从您的示例中不清楚是否要通过
format
方法格式化多个字段。如果是这种情况,那么您也许可以这样做:您可以像其他任何帮助器一样使用此帮助器:
并在您的视图中:
或
Place the logic that does your view assembly into a CardHelper:
app/helpers/card_helper.rb
It's not clear from your example whether you want to format several fields via the
format
method. If that's the case, then you might be able to do:You can use this helper like any other:
and in your views:
or
转义视图内容是视图的责任,这就是
h
帮助器在控制器或模型中不可用的原因。不过,我不明白为什么不能简单地清理视图中的内容。
另请注意,在 Rails 3 中,您不需要调用
h
帮助器。默认情况下,内容会自动清理,除非您将其标记为
html_safe!
。在模型中使用
h
帮助器在逻辑上不正确的主要原因是模型应该独立于视图工作。换句话说,模型不应该关心内容是否将嵌入 HTML 文档或 JSON 文件(与 HTML 相比,这需要不同的转义方法)。Escaping the content for view is a View responsibility, this is the reason why the
h
helper is not available in controllers or models.Still, I don't understand why can't you simply sanitize the content in the view.
Also note that, in Rails 3, you don't need to call the
h
helper.Content is sanitized automatically by default unless you flag it as
html_safe!
.The main reason why is not logically true to use the
h
helper in the model is because the model should work view-independently. In other words, the model should not care whether the content is going to be embedded in a HTML document or JSON file (which requires a different escaping approach compared to HTML).