在 Rails 3 的 JS/ERB 模板中处理 JSON

发布于 2024-09-24 06:09:19 字数 518 浏览 5 评论 0原文

我可以轻松地使用 JSON 对象和 jQuery-rails(jQuery 库加上一个特殊的rails.js 文件)与 Rails(3) 进行典型的 AJAX 调用。

不过,在一个控制器中,我想在 AJAX 调用后在 erb 模板 (create.js.erb) 中返回一些 JSON。

我已经尝试了控制器中的所有组合(@object.to_json、'[{"content":"hello world"}]' 等)和模板本身(JSON.parse()、单引号、双引号等),但对象继续像这样渲染:

'[{"groups":{},"created_at":"2010-09-21T03:49:34Z" ...

结果,我的 jQuery 代码无法解析它,并且出现错误。

我需要如何在控制器中准备我的对象,以及视图中需要什么 erb 语法才能将其呈现为有效的 JSON 对象?

非常感谢!

I have no trouble making typical AJAX calls to and from Rails(3) with JSON objects and jQuery-rails (jQuery library plus a special rails.js file).

In one controller, though, I want to RETURN some JSON in an erb template (create.js.erb) after an AJAX call.

I've tried every combination of things in the controller (@object.to_json, '[{"content":"hello world"}]', etc.) and in the template itself (JSON.parse(), single quotes, double quotes, etc.), but the object keeps on rendering like this:

'[{"groups":{},"created_at":"2010-09-21T03:49:34Z" ...

and as a result, my jQuery code cannot parse it and I get errors.

How do I need to prep my object in the controller, and what erb syntax do I need in the view for it to render as a valid JSON object?

Thanks so much!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

好久不见√ 2024-10-01 06:09:20

要返回 json,您必须在控制器中编写渲染,如下所示:

render :json => @object

并且 .to_json 将自动被调用。

如果您想包含一些关系,您可以执行以下操作:

render :json => @post.to_json(:include => [:comments, :authors])

我不确定使用 erb 来呈现您的 json 是否有效。

To return json you have to write your render in the controller as follows:

render :json => @object

and the .to_json will automatically be called.

If you would want to include some relations, you could do the following:

render :json => @post.to_json(:include => [:comments, :authors])

I am not sure if it would work to use an erb to render your json.

梦里°也失望 2024-10-01 06:09:20

您可以在控制器中调用 render ,但是如果您可能需要渲染多个部分以供处理程序进行后续 dom 插入,那么这将是一个问题。我需要将多个 html 片段设置为哈希,并且我已经能够返回 erb,它基本上使用 hash.to_json.html_safe,如 neutrino 上面建议的那样,并允许我在过程中渲染多个部分。

You can call render in your controller, but that will be a problem if you need to possibly render more than a few partials for subsequent dom insertion by the handler. I needed to set multiple html fragments into a hash, and I've been able to return erb which basically uses hash.to_json.html_safe as neutrino suggests above and allows me to render multiple partials in the process.

鸵鸟症 2024-10-01 06:09:20

仅需要 to_json.html_safe

> `'<script>'.to_json`
=> "\"\\u003cscript\\u003e\""

修补以使 to_json 响应 html_safe? 并自动返回 true

# just use .to_json instead of .to_json.html_safe
ActiveSupport::JSON.class_eval do
  class << self
    def encode_with_html_safe *args
      self.encode_without_html_safe(*args).html_safe
    end
    alias_method_chain :encode, :html_safe
  end
end

Only to_json.html_safe is needed:

> `'<script>'.to_json`
=> "\"\\u003cscript\\u003e\""

Patch to make to_json respond to html_safe? and return true automatically:

# just use .to_json instead of .to_json.html_safe
ActiveSupport::JSON.class_eval do
  class << self
    def encode_with_html_safe *args
      self.encode_without_html_safe(*args).html_safe
    end
    alias_method_chain :encode, :html_safe
  end
end
一片旧的回忆 2024-10-01 06:09:19

我不确定这就是原因,但您也可以尝试使用 html_safe 方法。 ERB 可能会转义您的 JSON,因为它认为它不是 html 安全的。尝试在使用字符串时调用该方法:

@object.to_json.html_safe

I'm not sure this is the cause, but you can also try playing around with html_safe method. ERB might be escaping your JSON because it thinks it's not html safe. Try calling that method when using the string:

@object.to_json.html_safe
┈┾☆殇 2024-10-01 06:09:19

单独使用 html_escaperaw 将使您易受 XSS 攻击

相反,定义一个合理版本的 json_escape (又名 j)帮助器:

module ActionView::Base
  def json_escape(s)
    result = s.to_s.gsub('/', '\/')
    s.html_safe? ? result.html_safe : result
  end

  alias j json_escape
end

像这样使用它:

<script>
  var Accounts = new Backbone.Collection;
  Accounts.reset(<%=j @accounts.to_json.html_safe %>);
  var Projects = new Backbone.Collection;
  Projects.reset(<%=j @projects.to_json(:collaborators => true).html_safe %>);
</script>

请参阅 这篇文章了解更多详细信息。

请注意,别名为 j 之间存在命名冲突。 ERB::Util 中的 code>json_escape 和 ActionView::Helpers::JavaScriptHelper 中的 j 别名为 escape_javascript。我希望 JavaScriptHelper 别名能够重命名为 js

Using html_escape or raw alone will leave you vulnerable to XSS.

Instead, define a sensible version of the json_escape (a.k.a. j) helper:

module ActionView::Base
  def json_escape(s)
    result = s.to_s.gsub('/', '\/')
    s.html_safe? ? result.html_safe : result
  end

  alias j json_escape
end

Use it like this:

<script>
  var Accounts = new Backbone.Collection;
  Accounts.reset(<%=j @accounts.to_json.html_safe %>);
  var Projects = new Backbone.Collection;
  Projects.reset(<%=j @projects.to_json(:collaborators => true).html_safe %>);
</script>

See this post for further details.

Be aware that there's a naming conflict between j aliased to json_escape in ERB::Util and j aliased to escape_javascript in ActionView::Helpers::JavaScriptHelper. It's my hope that the JavaScriptHelper alias will be renamed to js.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文