【问题标题】:Embedding JSON in a Rails 4 JS/ERB template在 Rails 4 JS/ERB 模板中嵌入 JSON
【发布时间】:2014-10-06 22:26:15
【问题描述】:

我正在尝试将模型数据嵌入到我的 RoR 4 应用程序中的一些 javascript 中。控制器正在为模型数据生成 JSON,如下所示...

def my_controller_method
  @person = Person.find(params[:id])
  @person_json = @person.to_json(only: [:name, :id])
end

我想在我不显眼的 javascript 中使用该 json 来使用 JSON.parse() 创建 javascript 对象...

var personJSON = <%= j @person_json %>;
var person = JSON.parse(personJSON);

但是生成的 javascript 是...

var personJSON = {\&quot;id\&quot;:1,\&quot;name\&quot;:\&quot;fred\&quot;};
var person = JSON.parse(personJSON);

并且 javascript 正在默默地失败。

在寻找解决方案时,我找到了this question asked on SO,但是当我尝试使用 html_safe 方法时,我的 rails 应用程序崩溃了,说 html_safe 是未知方法。

提前感谢您的帮助!

【问题讨论】:

    标签: javascript ruby-on-rails ruby json


    【解决方案1】:

    这个呢:

    var personJSON = <%= @person_json.to_json.html_safe %>
    

    var personJSON = <%= raw @person_json %>
    

    我认为最后一个选项更适合您的特定情况。

    【讨论】:

    • 谢谢,这解决了问题。我必须将它包装在一个 escape_javascript 调用中才能工作。问题,这容易受到 XSS 攻击吗?
    • 从 rails 3.x 开始,有一个 HTML 安全字符串的概念。 raw将对象转换为字符串,然后调用html_safe
    • 本文说明单独使用raw容易受到XSS攻击:jfire.io/blog/2012/04/30/…
    【解决方案2】:

    您需要使用 escape_javascript 转义 JSON:

    var personJSON = "<%= escape_javascript @person_json %>";
    

    您也可以将其缩短为:

    var personJSON = "<%= j @person_json %>";
    

    【讨论】:

    • 谢谢。当我这样做时,我的应用程序崩溃并出现错误 ActionView::Template::Error (undefined method gsub' for {"id"=>1, "name"=>"fred"}:Hash):`。你的想法?
    • as_json 返回一个哈希,而不是 JSON。请改用to_json(only: [:name, :id])
    • 好的,这使得崩溃消失了,但生成的 js 代码仍然是var personJSON = {\&amp;quot;id\&amp;quot;:1,\&amp;quot;name\&amp;quot;:\&amp;quot;fred\&amp;quot;};,这导致 javascript 静默失败。
    • 哦,字符串也需要引号。我会更新答案。
    • 好收获!仍然无法正常工作。解析时抛出异常,异常为“Unexpected token &”。再次感谢您的帮助!
    【解决方案3】:

    在我的 rails 5.0 上运行良好

    控制器

    # foo.rb
    @data = [{key1: 'value1', key2: 'value2'}, {key3: 'value3'}]
    

    查看

    # foo.js.erb
    var arr = JSON.parse("<%= escape_javascript(render(inline: @data.to_json)) %>")
    console.log(arr) # (2) [Object, Object]
    

    【讨论】:

      【解决方案4】:

      我喜欢使用 Jbuilder,所以在这种情况下,我曾经这样做过:

      var data = JSON.parse("<%= j raw render template: '/account/budget_item_elements/show.json.jbuilder' %>");
      

      在 show.json.jbuilder 中我可以:

      json.extract! @budget_item_element, :id, :name, :created_at, :updated_at
      

      【讨论】:

        【解决方案5】:

        我试图有条件地渲染只有一些双引号文本的文本,这最终成为我的解决方案

        <%= is_true ? raw(%(This is text not in quotes: "#{@foo.bar.name}")) : "" %>
        

        这是许多其他堆栈溢出帖子的大杂烩,当它们组合在一起时最终对我有用。

        【讨论】:

          猜你喜欢
          • 2011-04-15
          • 1970-01-01
          • 1970-01-01
          • 2017-12-10
          • 1970-01-01
          • 1970-01-01
          • 2014-03-11
          • 2014-01-24
          • 1970-01-01
          相关资源
          最近更新 更多