3

我有一个 Rails 3.2.13 应用程序,其中的标题包含站点名称和页面特定文本。公共部分在布局中定义,在每个 HAML 视图中定义页面特定部分。

首先我provide是这样使用的:

# layout.html.haml
%title= (content_for?(:title) ? "#{yield(:title)} | " : "") + "Chunky-B"

# show.html.haml
- provide(:title, @listing.name)

我的问题是,当从模型中提取页面特定内容时,它会被转义两次。如果@listing.name包含(未转义的)&符号我得到输出

<title>Bacon &amp;amp; Eggs | Chunky-B</title>

我最近改用gem作为我meta-tags标题和元描述,但同样的问题仍然存在。

我知道我需要一些组合hhtml_safe甚至可能raw。有了这个问题的答案和一些试验和错误,我可能会到达那里,但我以前不必绕过内置的转义,也不想冒着打开漏洞的风险来猜测自己。在写这个问题时,我有一种预感,但我敢打赌,热切的回答者会打败我。:)

4

3 回答 3

2

像往常一样,我一直在看答案。

(h @listing.name).html_safe我通过按照此评论使用得到了我想要的结果,如果我相信评论者它是“常见且可接受的使用”。

如果我理解正确,我会强制使用该名称进行转义h以保护我免受各种邪恶的侵害,然后将其标记为不需要任何额外的转义.html_safe调用。

一切看起来都很好,输出被转义一次并在我的浏览器标题栏中正确呈现。不过,我可以放心,这是安全可靠的。如果有人能给出一个高质量的答案,说明为什么我没有开箱即用地得到相同的结果,我会准备好将其标记为已接受。

于 2013-08-06T13:05:25.983 回答
0

我遇到了同样的事情,发现了一个比使用html_safe.

首先,更新的代码:

# layout.html.haml
%title = full_title("Chunky-B")

其中“safe_title”是:

def full_title(page_title)
  base_title = "".html_safe
  if content_for?(:title)
    base_title << yield(:title)
    base_title << " | "
  end
  base_title << page_title
  base_title
end

如果内容不安全,则会转义:title内容,但如果内容安全,则不会转义。(当然,您可能希望对此进行方法化,因为我已将您的单行代码变成了六行代码。)

这允许标题"Bacon & Eggs"正确显示,但也可以转义"<script>alert('foo')</script>"- 例如,如果某些恶意用户设法将自定义文本输入到标题标签中显示的字段中,或者如果您自己不小心使用了有风险的文本。

解释归结为这一点——'foo'.html_safe返回一个 ActiveSupport::SafeBuffer,它在所有方面都像一个字符串,除了一个:当你将一个字符串附加到一个安全缓冲区时(通过调用 + 或 <<),其他字符串之前是 HTML 转义的它被附加到 SafeBuffer 中。当您将另一个 SafeBuffer 附加到 SafeBuffer 时,不会发生转义。Rails 使用 SafeBuffers 在后台渲染您的所有视图,因此上述更新的方法最终为 Rails 提供了一个 SafeBuffer,我们已控制它以:title“按需”而不是“总是”执行转义。

现在,这个答案的功劳完全归于 Henning Koch,并且在你所知道的关于 html_safe 的一切都是错误的中进行了更详细的解释——我上面的回顾只是试图提供解释的本质,以防万一这个链接死了.

于 2015-04-23T06:44:46.023 回答
0

我遇到过这个问题,它似乎只在标题作为简单内容传递时才会发生:

content_for :title, 'Wow & Fail'
#=> Wow &amp;amp; Fail

但是当它作为一个块传递时,它会正确呈现:

content_for :title do
  'Wow & Fail'
#=> Wow & Fail

正如你在这里看到的那样https://github.com/rails/rails/blob/76c385709c873a7105e3a267d84c4e70417a15e2/actionview/lib/action_view/helpers/capture_helper.rb#L153

仅当您传递一个块时才使用捕获方法,该块利用 active_support 的 output_safety https://github.com/rails/rails/blob/76c385709c873a7105e3a267d84c4e70417a15e2/actionview/lib/action_view/helpers/capture_helper.rb#L41

于 2017-04-03T18:36:39.387 回答