119 votes

Rendu JSON dans le contrôleur

J'étais en train de lire un livre et dans un chapitre sur les contrôleurs, quand il est question de rendre des choses, pour JSON, il y a un exemple comme celui-ci mais il n'entre pas dans les détails, donc je n'ai pas pu comprendre l'image globale dans laquelle cet exemple s'inscrit :

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

Et aussi quelques exemples avec JSONP en l'utilisant avec des fonctions de rappel :

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

Quelqu'un peut-il les expliquer ?

139voto

Sean Vieira Points 47080

Vous allez normalement revenir JSON soit parce que :

A) Vous construisez une partie ou la totalité de votre application en tant qu'application à page unique (SPA) et vous avez besoin que votre JavaScript côté client soit capable d'extraire des données supplémentaires sans recharger entièrement la page.

o

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

Ou, peut-être, vous mangez votre propre nourriture pour chien et faites <em>les deux</em>

Dans les deux cas render :json => some_data JSON-ifiera les données fournies. Le site :callback dans le deuxième exemple nécessite un peu plus d'explications (voir ci-dessous), mais il s'agit d'une autre variation sur la même idée (retourner 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 l'obstacle de la Politique de l'origine identique qui fait partie de la sécurité intégrée de chaque navigateur. Si vous avez votre API à api.yoursite.com et vous servirez votre application à partir de services.yoursite.com votre JavaScript ne sera pas (par défaut) en mesure de faire XMLHttpRequest (XHR - aka ajax) à partir de services a api . La façon dont les gens se sont faufilés autour de cette limitation (avant que les La spécification sur le partage des ressources entre origines a été finalisée. ) est d'envoyer les données JSON à partir du serveur. comme s'il s'agissait de JavaScript au lieu de JSON ). Ainsi, plutôt que de renvoyer :

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

que le serveur renverrait à la place :

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

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

77voto

Max Points 3568

Que voulez-vous 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 et vous verrez une sortie JSON. render :json appelle essentiellement to_json et renvoie le résultat au navigateur avec les en-têtes corrects. Ceci est utile pour les appels AJAX en JavaScript où vous souhaitez renvoyer des objets JavaScript à utiliser. En outre, vous pouvez utiliser la fonction callback pour spécifier le nom de la fonction de rappel que vous souhaitez appeler via JSONP.

Par exemple, disons que nous avons un User qui ressemble à ceci : {name: 'Max', email:' m@m.com'}

Nous avons également 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 voir, nous avons réussi à obtenir l'utilisateur avec l'id 5 de notre application rails et à l'utiliser dans notre code JavaScript car il a été renvoyé sous forme d'objet JSON. L'option callback appelle simplement une fonction JavaScript du nom passé avec l'objet JSON comme premier et seul argument.

Pour donner un exemple de la callback regardez ce qui suit :

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

Maintenant nous pouvons créer une requête 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 de l'utilisation d'un tel rappel est généralement de contourner les protections du navigateur qui limitent le partage des ressources entre origines (CORS). JSONP n'est cependant plus très utilisé, car il existe d'autres techniques plus sûres et plus simples pour contourner CORS.

19voto

Kelly Points 8780

Pour l'instance de

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

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

Pour l'instance de

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

Vous déclarez que vous voulez rendre @projects en tant que JSON, et d'envelopper ces données dans un appel javascript qui rendra un peu comme :

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

Cela permet d'envoyer les données à la fenêtre parent et de contourner les problèmes de falsification intersites.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X