컨트롤러에서 JSON 렌더링


103

나는 책을 읽고 컨트롤러에 관한 장에서 물건을 렌더링하는 것에 대해 이야기 할 때 JSON의 경우 이와 같은 예제가 있지만 자세한 내용은 다루지 않으므로이 예제가 맞는 더 큰 그림을 파악할 수 없습니다.

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

콜백 함수와 함께 사용하는 JSONP의 몇 가지 예 :

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

누군가 이것을 설명 할 수 있습니까?

답변:


127

일반적으로 다음과 같은 이유로 JSON을 반환 합니다.

A) 애플리케이션의 일부 / 전체를 단일 페이지 애플리케이션 (SPA)으로 빌드하고 있으며 페이지를 완전히 다시로드하지 않고도 추가 데이터를 가져올 수 있으려면 클라이언트 측 JavaScript가 필요합니다.

또는

B) 제 3자가 사용할 API를 구축하고 있으며 데이터를 직렬화하기 위해 JSON을 사용하기로 결정했습니다.

또는 자신의 dogfood를 먹고 둘 다

두 경우 모두 render :json => some_data제공된 데이터를 JSON 화합니다. :callback두 번째 예제 의 키는 좀 더 설명이 필요하지만 (아래 참조) 동일한 아이디어에 대한 또 다른 변형입니다 (JavaScript가 쉽게 처리 할 수있는 방식으로 데이터 반환).

:callback?

JSONP (두 번째 예)는 모든 브라우저에 내장 된 보안의 일부인 동일한 출처 정책 을 우회하는 방법입니다 . 에 API api.yoursite.com가 있고 services.yoursite.comJavaScript에서 애플리케이션을 제공하는 경우 (기본적으로)에서 XMLHttpRequest(XHR-ajax) 요청을 services할 수 없습니다 api. 사람들이 이러한 제한 ( Cross-Origin Resource Sharing 사양이 확정 되기 전)에 몰래 들어가는 방식 은 JSON 데이터 가 JSON 대신 JavaScript 인 것처럼 서버에서 JSON 데이터를 전송하는 것입니다 . 따라서 다시 보내는 대신 :

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

대신 서버는 다음을 다시 보냅니다.

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

그러므로, 클라이언트 측 JS 프로그램은 작성할 수 script의 태그 가리키는 api.yoursite.com/your/endpoint?name=John앤드가 valueOfCallbackHere호출 (클라이언트 측 JS로 정의되어야 할 것이다) 기능 이 다른 출처로부터 데이터를 ).


이러한 기술을 전혀 사용하지 않고 대신 JSON-JBuilder 및 Eager Loading을 사용하는 것이 더 낫습니까? 아니면 나는 혼란스럽고 두 가지 다른 것입니다.?

1
@ user1899082-이러한 기술은 실제로 JBuilder를 사용할 때 걱정하는 것보다 낮은 수준의 개념입니다. 예를 들어 JBuilder를 사용하여 to_json메서드 내에서 객체를 직렬화하기 쉽게 만들 수없는 이유가 없습니다. 둘을 일치시키는 render :json => some_object_that_uses_JBuilder_to_render_its_json것은 (내가 말할 수있는 한) 합법적입니다.
Sean Vieira 2013

감사합니다 Sean, 귀하의 설명은 콜백으로 json을 렌더링하는 데 도움이되었으며 이것은 내 문제 중 하나를 해결했습니다.
Abhi

67

정확히 무엇을 알고 싶으십니까? ActiveRecord에는 레코드를 JSON으로 직렬화하는 메서드가 있습니다. 예를 들어 Rails 콘솔을 열고 들어가면 ModelName.all.to_jsonJSON 출력이 표시됩니다. render :json기본적으로 to_json올바른 헤더를 사용하여 브라우저에 결과를 호출 하고 반환합니다. 이것은 사용할 JavaScript 객체를 반환하려는 JavaScript의 AJAX 호출에 유용합니다. 또한 callback옵션을 사용하여 JSONP를 통해 호출하려는 콜백의 이름을 지정할 수 있습니다 .

예를 들어 User다음과 같은 모델이 있다고 가정 해 보겠습니다 .{name: 'Max', email:' m@m.com'}

다음과 같은 컨트롤러도 있습니다.

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
    }        
});

보시다시피, 우리는 Rails 앱에서 ID가 5 인 사용자를 가져 와서 JSON 객체로 반환되었으므로 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 (Cross Origin Resource Sharing)를 제한하는 브라우저 보호를 우회하는 것입니다. 그러나 더 안전하고 쉬운 CORS를 우회하기위한 다른 기술이 존재하기 때문에 JSONP는 더 이상 많이 사용되지 않습니다.


예제를 조금 확장 할 수 있습니까? 메서드에 callback:옵션을 추가 한 render다음 Ajax호출 내부에 표시합니다 .
Arup에 Rakshit

15

예를 들어

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

@projectsJSON 으로 렌더링 tasks하고 내 보낸 데이터의 프로젝트 모델에 대한 연관 을 포함 하려고한다고 지정합니다 .

예를 들어

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

@projectsJSON 으로 렌더링 하고 다음과 같이 렌더링되는 javascript 호출로 해당 데이터를 래핑한다고 말하고 있습니다.

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

이를 통해 데이터가 상위 창으로 전송되고 교차 사이트 위조 문제를 우회 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.