web-dev-qa-db-ja.com

コントローラーでのJSONのレンダリング

私は本を​​読んでいて、コントローラについての章でレンダリングのことについて話していました.JSONの場合、このような例がありますが、詳細には入らないため、この例が収まる全体像を理解できませんでした:

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

また、コールバック関数でそれを使用するJSONPの例:

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

誰かがこれらを説明できますか?

90
user1899082

通常、次のいずれかの理由で JSON を返します。

A)アプリケーションの一部/すべてを単一ページアプリケーション(SPA)として構築しており、ページを完全にリロードすることなく追加のデータを取り込むことができるクライアント側のJavaScriptが必要です。

または

B)サードパーティが使用するAPIを構築しているため、JSONを使用してデータをシリアル化することにしました。

または、おそらく、あなたはあなた自身のドッグフードを食べて、both

どちらの場合も、render :json => some_dataは提供されたデータをJSON化します。 2番目の例の:callbackキーにはもう少し説明が必要ですが(以下を参照)、同じ考え方の別のバリエーションです(JavaScriptが簡単に処理できる方法でデータを返す)。

なぜ:callbackですか?

JSONP(2番目の例)は、すべてのブラウザーの組み込みセキュリティの一部である Same Origin Policy を回避する方法です。 api.yoursite.comにAPIがあり、services.yoursite.comからアプリケーションを提供する場合、JavaScriptは(デフォルトで)XMLHttpRequestからservicesへのapi(XHR-別名ajax)リクエストを行うことができません。 ( Cross-Origin Resource Sharing仕様が完成する前に )人々がその制限をこっそりとこしている方法は、サーバーからJSONデータを送信することですJSONの代わりにJavaScriptであるかのように)。したがって、返送するのではなく:

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

サーバーは代わりに送り返します:

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

したがって、クライアント側のJSアプリケーションは、api.yoursite.com/your/endpoint?name=Johnを指すscriptタグを作成し、valueOfCallbackHere関数(クライアント側のJSで定義する必要があります)をと呼ばれる他のOrigin。)

114
Sean Vieira

正確に何を知りたいですか? ActiveRecordには、レコードをJSONにシリアル化するメソッドがあります。たとえば、Railsコンソールを開き、ModelName.all.to_jsonと入力すると、JSON出力が表示されます。 render :jsonは本質的にto_jsonを呼び出し、正しいヘッダーで結果をブラウザに返します。これは、使用するJavaScriptオブジェクトを返すJavaScriptのAJAX呼び出しに役立ちます。さらに、callbackオプションを使用して、JSONPを介して呼び出したいコールバックの名前を指定できます。

たとえば、次のようなUserモデルがあるとします:{name: 'Max', email:' [email protected]'}

次のようなコントローラーもあります。

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

さて、次のようにjQueryを使用してAJAX呼び出しを行うと:

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

ご覧のとおり、JSONオブジェクトとして返されたため、Railsアプリからid 5のユーザーを取得し、JavaScriptコードで使用することができました。コールバックオプションは、JSONオブジェクトを最初の唯一の引数として渡された名前付きのJavaScript関数を呼び出すだけです。

callbackオプションの例を示すには、次をご覧ください。

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

これで、次のようにJSONPリクエストを作成できます。

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

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

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

このようなコールバックを使用する動機は、通常、クロスオリジンリソース共有(CORS)を制限するブラウザー保護を回避することです。ただし、安全で簡単なCORSを回避するための他の手法が存在するため、JSONPはそれほど使用されなくなりました。

61
Max

インスタンスの

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

@projectsをJSONとしてレンダリングし、エクスポートされたデータのProjectモデルに関連tasksを含めることを表明しています。

インスタンスの

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

@projectsをJSONとしてレンダリングし、そのデータを次のようにレンダリングするjavascript呼び出しでラップすることを表明しています。

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

これにより、データを親ウィンドウに送信し、クロスサイト偽造の問題を回避できます。

13
Kelly