Ruby-on-rails 在控制器中渲染 JSON
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14824551/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rendering JSON in controller
提问by Sean Vieira
I was reading a book and in a chapter about Controllers when it talks about rendering stuff, for JSON it has an example like this but doesn't go in to details so I couldn't figure out the bigger picture that this example fits in:
我正在阅读一本书和关于控制器的一章,当它谈到渲染东西时,对于 JSON,它有一个这样的例子,但没有详细介绍,所以我无法弄清楚这个例子适合的更大的图景:
render :json => @projects, :include => tasks
And also some example with JSONP using it with callback functions:
还有一些使用 JSONP 和回调函数的例子:
render :json => @record, :callback => 'updateRecordDisplay'
Can someone explain these?
有人可以解释这些吗?
回答by Sean Vieira
You'll normally be returning JSONeither because:
您通常会因为以下原因返回JSON:
A) You are building part / all of your application as a Single Page Application (SPA) and you need your client-side JavaScript to be able to pull in additional data without fully reloading the page.
A) 您正在将部分/全部应用程序构建为单页应用程序 (SPA),并且您需要客户端 JavaScript 能够在不完全重新加载页面的情况下提取额外数据。
or
或者
B) You are building an API that third parties will be consuming and you have decided to use JSON to serialize your data.
B) 您正在构建一个第三方将使用的 API,并且您已决定使用 JSON 来序列化您的数据。
Or, possibly, you are eating your own dogfood and doing both
或者,您可能正在吃自己的狗粮并且两者都做
In both cases render :json => some_datawill JSON-ify the provided data. The :callbackkey in the second example needs a bit more explaining (see below), but it is another variation on the same idea (returning data in a way that JavaScript can easily handle.)
在这两种情况下,render :json => some_data都会对提供的数据进行 JSON 化。:callback第二个示例中的关键需要更多解释(见下文),但它是同一想法的另一种变体(以 JavaScript 可以轻松处理的方式返回数据。)
Why :callback?
为什么:callback?
JSONP (the second example) is a way of getting around the Same Origin Policythat is part of every browser's built-in security. If you have your API at api.yoursite.comand you will be serving your application off of services.yoursite.comyour JavaScript will not (by default) be able to make XMLHttpRequest(XHR - aka ajax) requests from servicesto api. The way people have been sneaking around that limitation (before the Cross-Origin Resource Sharing spec was finalized) is by sending the JSON data over from the server as if it was JavaScript instead of JSON). Thus, rather than sending back:
JSONP(第二个示例)是一种绕过作为每个浏览器内置安全性的一部分的同源策略的方法。如果你有你的API api.yoursite.com,您将服务应用程序关闭的services.yoursite.com您的JavaScript不会(默认情况下)能够使XMLHttpRequest(XHR -又名AJAX)从请求services到api。人们绕过该限制的方式(在跨域资源共享规范最终确定之前)是通过从服务器发送 JSON 数据,就好像它是 JavaScript 而不是 JSON 一样)。因此,而不是发回:
{"name": "John", "age": 45}
the server instead would send back:
服务器反而会发回:
valueOfCallbackHere({"name": "John", "age": 45})
Thus, a client-side JS application could create a scripttag pointing at api.yoursite.com/your/endpoint?name=Johnand have the valueOfCallbackHerefunction (which would have to be defined in the client-side JS) called with the data from this other origin.)
因此,客户端 JS 应用程序可以创建一个script指向的标记,api.yoursite.com/your/endpoint?name=John并使用来自其他源的数据valueOfCallbackHere调用函数(必须在客户端 JS 中定义)。)
回答by Max
What exactly do you want to know? ActiveRecord has methods that serialize records into JSON. For instance, open up your rails console and enter ModelName.all.to_jsonand you will see JSON output. render :jsonessentially calls to_jsonand returns the result to the browser with the correct headers. This is useful for AJAX calls in JavaScript where you want to return JavaScript objects to use. Additionally, you can use the callbackoption to specify the name of the callback you would like to call via JSONP.
你究竟想知道什么?ActiveRecord 具有将记录序列化为 JSON 的方法。例如,打开 Rails 控制台并输入ModelName.all.to_json,您将看到 JSON 输出。render :json本质上调用to_json并将结果返回给带有正确标题的浏览器。这对于在 JavaScript 中要返回要使用的 JavaScript 对象的 AJAX 调用很有用。此外,您可以使用该callback选项指定要通过 JSONP 调用的回调的名称。
For instance, lets say we have a Usermodel that looks like this: {name: 'Max', email:' [email protected]'}
例如,假设我们有一个如下所示的User模型:{name: 'Max', email:' [email protected]'}
We also have a controller that looks like this:
我们还有一个看起来像这样的控制器:
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
render json: @user
end
end
Now, if we do an AJAX call using jQuery like this:
现在,如果我们像这样使用 jQuery 进行 AJAX 调用:
$.ajax({
type: "GET",
url: "/users/5",
dataType: "json",
success: function(data){
alert(data.name) // Will alert Max
}
});
As you can see, we managed to get the User with id 5 from our rails app and use it in our JavaScript code because it was returned as a JSON object. The callback option just calls a JavaScript function of the named passed with the JSON object as the first and only argument.
如您所见,我们设法从 Rails 应用程序中获取了 id 为 5 的用户,并在我们的 JavaScript 代码中使用它,因为它是作为 JSON 对象返回的。回调选项只是调用一个带有 JSON 对象作为第一个也是唯一参数传递的命名的 JavaScript 函数。
To give an example of the callbackoption, take a look at the following:
要给出该callback选项的示例,请查看以下内容:
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
render json: @user, callback: "testFunction"
end
end
Now we can crate a JSONP request as follows:
现在我们可以创建一个 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);
The motivation for using such a callback is typically to circumvent the browser protections that limit cross origin resource sharing (CORS). JSONP isn't used that much anymore, however, because other techniques exist for circumventing CORS that are safer and easier.
使用此类回调的动机通常是为了规避限制跨源资源共享 (CORS) 的浏览器保护措施。然而,JSONP 已不再使用那么多,因为存在其他更安全、更容易绕过 CORS 的技术。
回答by Kelly
For the instance of
例如
render :json => @projects, :include => :tasks
You are stating that you want to render @projectsas JSON, and include the association taskson the Project model in the exported data.
您声明要呈现@projects为 JSON,并tasks在导出的数据中包含Project 模型上的关联。
For the instance of
例如
render :json => @projects, :callback => 'updateRecordDisplay'
You are stating that you want to render @projectsas JSON, and wrap that data in a javascript call that will render somewhat like:
您声明要呈现@projects为 JSON,并将该数据包装在一个 javascript 调用中,该调用将呈现如下:
updateRecordDisplay({'projects' => []})
This allows the data to be sent to the parent window and bypass cross-site forgery issues.
这允许将数据发送到父窗口并绕过跨站点伪造问题。

