wake-up-neo.com

Umgang mit JSON in der JS/ERB-Vorlage in Rails 3

Ich habe keine Schwierigkeiten, typische AJAX-Aufrufe von und nach Rails (3) mit JSON-Objekten und jQuery-Rails (jQuery-Bibliothek plus eine spezielle Rails.js-Datei) durchzuführen.

In einem Controller möchte ich jedoch nach einem AJAX -Aufruf etwas JSON in einer erb-Vorlage (create.js.erb) zurückgeben.

Ich habe jede Kombination von Dingen im Controller (@ object.to_json, '[{"content": "hallo world"}]' usw.) und in der Vorlage selbst (JSON.parse (), einfache Anführungszeichen) ausprobiert. Anführungszeichen usw.), das Objekt wird jedoch wie folgt gerendert:

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

mein jQuery-Code kann daher nicht analysiert werden und ich bekomme Fehler. 

Wie muss ich mein Objekt im Controller vorbereiten, und welche Erbssyntax benötige ich in der Ansicht, damit es als gültiges JSON-Objekt dargestellt werden kann?

Vielen Dank!

32
Michael Waxman

Ich bin nicht sicher, ob dies die Ursache ist, aber Sie können auch mit der html_safe-Methode herumspielen. ERB könnte Ihrem JSON entgehen, weil er der Meinung ist, dass es nicht html-sicher ist. Rufen Sie diese Methode auf, wenn Sie die Zeichenfolge verwenden:

@object.to_json.html_safe
54
alex.zherdev

Wenn Sie html_escape oder raw alleine verwenden, bleiben Sie anfällig für XSS .

Definieren Sie stattdessen eine sinnvolle Version des Helpers json_escape (a.k.a. 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

Verwenden Sie es so:

<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>

Siehe diesen Beitrag für weitere Details.

Beachten Sie, dass es einen Namenskonflikt gibt zwischen j in json_escape in ERB :: Util und j in escape_javascript in ActionView :: Helpers :: JavaScriptHelper. Ich hoffe, dass der JavaScriptHelper-Alias ​​in js umbenannt wird.

32
John

Um json zurückzugeben, müssen Sie Ihren Render wie folgt in den Controller schreiben:

render :json => @object

und der .to_json wird automatisch aufgerufen.

Wenn Sie einige Beziehungen hinzufügen möchten, können Sie Folgendes tun:

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

Ich bin mir nicht sicher, ob es funktionieren würde, wenn Sie Ihren Json mit einem Ebb rendern würden.

1
nathanvda

Nur to_json.html_safe wird benötigt: 

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

Patchen, damit to_json auf html_safe? reagiert und true automatisch zurückgegeben wird:

# 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

Sie können Render in Ihrem Controller aufrufen. Dies ist jedoch ein Problem, wenn Sie möglicherweise mehr als einige Partials für das nachfolgende Dom-Einfügen durch den Handler rendern müssen. Ich musste mehrere HTML-Fragmente in einen Hash setzen, und ich war in der Lage, erb zurückzugeben, das im Wesentlichen hash.to_json.html_safe verwendet, da Neutrino dies vorschlägt und mir ermöglicht, mehrere Partials im Prozess zu rendern. 

0
wkhatch