【问题标题】:How to output html_safe within <%=%> block while concatenating strings?如何在连接字符串时在 <%=%> 块内输出 html_safe?
【发布时间】:2012-05-01 05:14:20
【问题描述】:

考虑一下:

<%
str = "http://domain.com/?foo=1&bar=2"
%>

现在这些情况:

<%=str%>
# output:http://domain.com/?foo=1&amp;bar=2

<%=str.html_safe%>
# output:http://domain.com/?foo=1&bar=2

<%="#{str.html_safe}"%>
# output:http://domain.com/?foo=1&amp;bar=2

<%=""+str.html_safe%>
# output:http://domain.com/?foo=1&amp;bar=2

我需要输出带有其他字符串的 URL。我如何保证与符号不会被转义?由于我无法控制的原因,我无法发送&amp;amp;

请帮忙!把我的头发拉到这里:\

编辑:为了澄清,我实际上有一个这样的数组:

@images = [{:id=>"fooid",:url=>"http://domain.com/?foo=1&bar=2"},...]

我正在创建一个 JS 数组(image_array var)以通过这种方式在我的应用程序中使用:

image_array.push(<%=@images.map{|x|"{id:'#{x[:id]}',url:'#{x[:url].html_safe}'}"}.join(",")%>);

这会生成:

image_array.push({id:'fooid',url:'http://domain.com/?foo=1&amp;bar=2'},...);

这在我的具体情况下不起作用。我需要没有amp; 部分的url

【问题讨论】:

  • 这就是“我无法控制的原因”部分发挥作用的地方......我没有做接收器,也无法控制......这是一张图片src.. . 不,这有什么不同
  • @phrogz 添加了一个可能有帮助的说明...谢谢
  • 我已经删除了所有的噪音。请注意,如果您位于 &lt;script&gt;in XHTML 内(但如果您是 in HTML,则不需要)。
  • 知道了。我改写了这个问题,以便更清楚我要解决的问题。我真的不想知道 &lt;%=&lt;%=#{ 的区别,但是如何在一组连接的字符串中输出 html_safe ......正如你从上面的案例 4 中看到的那样:&lt;%=""+str.html_safe 不起作用要么

标签: ruby-on-rails ruby ruby-on-rails-3


【解决方案1】:

为了安全起见,你会做的是:

image_array.push(<%= @images.map { |image| image.as_json(only: [:id, :url]) }.to_json } %>)

这将像这样正确地转义 &lt;&gt; 等:

[{"name":"\u003ch1\u003eAAAA\u003c/h1\u003e"}]

对于像我这样想要连接字符串的人来说,这样做并不安全,最好的方法是连接标签,例如

    content_tag(:p) do
      content_tag(:span, "<script>alert(1)</script>") +
        link_to("show", user)
    end

可以正常工作并正确转义第一个字符串

【讨论】:

    【解决方案2】:
    image_array.push(<%= @images.map{|x| "{id:'#{x[:id]}',url:'#{x[:url]}'}".html_safe }.join(",") %>);
    

    【讨论】:

    • 不,一旦你调用 join 而不是数组,你将创建一个不再被标记为安全的新字符串。
    • 我同意,如果我没有在 RoR 3.2 上自己测试过的话。将结果打印到日志并且它有效。虽然我会质疑这是否是预期的结果,但 & 是正确未转义的。
    【解决方案3】:

    当你写作时:

    "#{foo.bar}"
    

    这~相当于写作

    foo.bar.to_s
    

    所以你实际上在做的是:

    <%=str.html_safe.to_s%>
    

    …Rails 不再认为它是安全的,因此它会通过一轮 HTML 转义来命中你的结果字符串。

    我不知道 Rails 的内部结构,但我假设 html_safe 方法使用实例变量扩展字符串对象,将其标记为 OK,但是当您通过插值将其包装在另一个字符串中时得到一个没有那个标志的新字符串。

    编辑:要满足您的需求,请在最终字符串上使用raw 或调用html_safe

    <%=raw "foo#{str}"%>
    <%="foo#{str}".html_safe%>
    

    或者在你的情况下:

    image_array.push(<%=raw @images.map{…}.join(',')%>);
    image_array.push(<%=@images.map{…}.join(',').html_safe%>);
    

    另见this question

    【讨论】:

    • 但是如何在串联中输出html_safe 字符串?
    • 顺便说一句,你为什么要手动生成 JSON 而不是使用标准的 JSON 生成?
    • 总是很高兴看到一些解释,让人们知道发生了什么。
    • 公平地说,rails 这样做是因为连接一个安全字符串和一个不安全字符串确实会导致一个不安全字符串,因此请始终小心你的 raw/html_safe
    【解决方案4】:

    使用这个

        <%=str.html_safe.to_s%>
    

       <%=raw(str)%>   
    

    给你更好的结果

    【讨论】:

    • 如何将其连接到同一 &lt;% 块中的另一个字符串?
    猜你喜欢
    • 2020-02-24
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-16
    • 2020-02-28
    • 1970-01-01
    相关资源
    最近更新 更多