web-dev-qa-db-ja.com

Rails 3のJS / ERBテンプレートでJSONを処理する

JSONオブジェクトとjQuery-Rails(jQueryライブラリと特別なRails.jsファイル)を使用してRails(3)との間で典型的なAJAX呼び出しを行うことは問題ありません)。

ただし、1つのコントローラーでは、AJAX呼び出しの後で、erbテンプレート(create.js.erb)にJSONを返します。

コントローラ(@ object.to_json、 '[{"content": "hello world"}]'など)とテンプレート自体(JSON.parse()、単一引用符)のあらゆる組み合わせを試しました二重引用符など)、ただし、オブジェクトは次のようにレンダリングを続けます:

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

その結果、私のjQueryコードはそれを解析できず、エラーが発生します。

コントローラーでオブジェクトを準備する方法、およびビューで有効なJSONオブジェクトとしてレンダリングするためにビューで必要なerb構文はどのように必要ですか?

本当にありがとう!

32
Michael Waxman

これが原因かどうかはわかりませんが、html_safeメソッドを試してみることもできます。 ERBはHTMLが安全でないと考えているため、JSONをエスケープしている可能性があります。文字列を使用するときにそのメソッドを呼び出してみてください。

@object.to_json.html_safe
54
alex.zherdev

html_escapeまたはrawを単独で使用すると、 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>

詳細は この投稿 を参照してください。

ERB :: Utilでjson_escapeにエイリアスされたjとActionViewでescape_javascriptにエイリアスされたjの間に 名前の競合 があることに注意してください。 :Helpers :: JavaScriptHelper。 JavaScriptHelperエイリアスの名前がjsに変更されることを願っています。

32
John

jsonを返すには、次のようにレンダリングをコントローラーに書き込む必要があります。

render :json => @object

そしてその .to_jsonが自動的に呼び出されます。

いくつかの関係を含める場合は、次のようにします。

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

あなたのjsonをレンダリングするためにerbを使用することがうまくいくかどうかはわかりません。

1
nathanvda

to_json.html_safeのみが必要です:

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

to_jsonhtml_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
0
brauliobo

コントローラーでrenderを呼び出すことができますが、ハンドラーによるその後のdom挿入のために複数のパーシャルをレンダリングする必要がある場合は問題になります。私は複数のhtmlフラグメントをハッシュに設定する必要があり、基本的にhash.to_json.html_safeを使用するerbを返すことができ、ニュートリノが上記で示唆しているように、プロセスで複数のパーシャルをレンダリングできます。

0
wkhatch