web-dev-qa-db-fra.com

Rendu JSON dans le contrôleur

Je lisais un livre et un chapitre sur Controllers qui traitait du rendu, mais JSON en donne un exemple comme celui-ci, mais n'entre pas dans les détails, je ne pouvais donc pas comprendre le tableau dans son ensemble:

render :json => @projects, :include => tasks

Et aussi quelques exemples d'utilisation de JSONP avec des fonctions de rappel:

render :json => @record, :callback => 'updateRecordDisplay'

Quelqu'un peut-il expliquer ces?

92
user1899082

Vous retournerez normalement JSON soit parce que:

A) Vous construisez une partie/la totalité de votre application sous la forme d'une application à page unique (SPA) et vous avez besoin de votre JavaScript côté client pour pouvoir extraire des données supplémentaires sans recharger complètement la page.

ou

B) Vous construisez une API consommée par des tiers et vous avez décidé d'utiliser JSON pour sérialiser vos données.

Ou, éventuellement, vous mangez votre propre nourriture pour chien et faites les deux

Dans les deux cas, render :json => some_data sera JSON-ify les données fournies. La touche :callback dans le deuxième exemple nécessite un peu plus d'explications (voir ci-dessous), mais il s'agit d'une autre variante de la même idée (renvoyer des données d'une manière que JavaScript peut facilement gérer.)

Pourquoi :callback?

JSONP (le deuxième exemple) est un moyen de contourner le Same Origin Policy qui fait partie de la sécurité intégrée de chaque navigateur. Si vous avez votre API à api.yoursite.com et que vous servirez votre application à partir de services.yoursite.com, votre JavaScript ne pourra pas (par défaut) faire des demandes de XMLHttpRequest (XHR - aka ajax) à partir de services à api. La façon dont les gens se sont faufilés autour de cette limitation (avant la finalisation de la partage de la spécification de ressources cross-origin ) consiste à envoyer les données JSON du serveur comme si était JavaScript au lieu de JSON ). Ainsi, plutôt que de renvoyer:

{"name": "John", "age": 45}

le serveur à la place renverrait:

valueOfCallbackHere({"name": "John", "age": 45})

Ainsi, une application JS côté client pourrait créer une balise script pointant vers api.yoursite.com/your/endpoint?name=John et avoir la fonction valueOfCallbackHere (qui devrait être définie dans le JS côté client) appelée avec les données de cette autre origine .)

116
Sean Vieira

Qu'est ce que tu veux savoir exactement? ActiveRecord a des méthodes qui sérialisent les enregistrements en JSON. Par exemple, ouvrez votre console Rails et entrez ModelName.all.to_json pour afficher la sortie JSON. render :json appelle essentiellement to_json et renvoie le résultat au navigateur avec les en-têtes appropriés. Ceci est utile pour les appels AJAX en JavaScript dans lesquels vous souhaitez renvoyer des objets JavaScript à utiliser. De plus, vous pouvez utiliser l'option callback pour spécifier le nom du rappel que vous souhaitez appeler via JSONP.

Par exemple, disons que nous avons un modèle User qui ressemble à ceci: {name: 'Max', email:' [email protected]'}

Nous avons aussi un contrôleur qui ressemble à ceci:

class UsersController < ApplicationController
    def show
        @user = User.find(params[:id])
        render json: @user
    end
end

Maintenant, si nous faisons un appel AJAX en utilisant jQuery comme ceci:

$.ajax({
    type: "GET",
    url: "/users/5",
    dataType: "json",
    success: function(data){
        alert(data.name) // Will alert Max
    }        
});

Comme vous pouvez le constater, nous avons réussi à obtenir l’utilisateur portant l’ID 5 à partir de notre application Rails et à l’utiliser dans notre code JavaScript car il a été renvoyé sous forme d’objet JSON. L'option de rappel appelle simplement une fonction JavaScript du nom nommé transmise avec l'objet JSON en tant que premier et unique argument.

Pour donner un exemple de l'option callback, examinez les éléments suivants:

class UsersController < ApplicationController
    def show
        @user = User.find(params[:id])
        render json: @user, callback: "testFunction"
    end
end

Nous pouvons maintenant créer une demande JSONP comme suit:

function testFunction(data) {
    alert(data.name); // Will alert Max
};

var script = document.createElement("script");
script.src = "/users/5";

document.getElementsByTagName("head")[0].appendChild(script);

La motivation pour utiliser un tel rappel est généralement de contourner les protections de navigateur qui limitent le partage de ressources croisées (CORS). Cependant, JSONP n'est plus très utilisé, car il existe d'autres techniques plus simples et plus sûres pour contourner les CORS.

62
Max

Pour l'instance de

render :json => @projects, :include => :tasks

Vous déclarez que vous souhaitez rendre @projects en tant que JSON et inclure l'association tasks du modèle de projet dans les données exportées.

Pour l'instance de

render :json => @projects, :callback => 'updateRecordDisplay'

Vous déclarez que vous souhaitez rendre @projects en tant que JSON et encapsuler ces données dans un appel javascript qui donnera un rendu similaire à celui-ci:

updateRecordDisplay({'projects' => []})

Cela permet aux données d'être envoyées à la fenêtre parente et de contourner les problèmes de falsification entre sites.

13
Kelly