对JSONP请求如何工作感到困惑

时间:2022-12-06 21:14:30

I am having trouble understanding the details of how a jsonp request works. I have read several sources including the wiki on jsonp and am still very confused on how the callback actually gets a hold of the function returned from the server when a jsonp call is made. For example, in the wiki, the source of the request is set as:

我无法理解jsonp请求如何工作的细节。我已经阅读了包括jsonp上的wiki在内的几个源文件,但仍然对在进行jsonp调用时回调如何实际获得从服务器返回的函数感到非常困惑。例如,在wiki中,请求的源设置为:

src="http://server2.example.com/RetrieveUser?UserId=1234&jsonp=parseResponse"

What exactly does jsonp = parseResponse actually do/mean?? Then they go on to say that the payload is:

jsonp = parseResponse到底是什么意思?然后他们接着说有效载荷是:

parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7});

How does this work? I am confused on the whole callback functionality. The function name parseResponse is passed to the server and somehow the data returned becomes parameters to this function? Can someone please clearly explain exactly how data is retrieved/used from a jsonp request?

这是如何工作的呢?我对整个回调功能感到困惑。函数名parseResponse被传递给服务器,以某种方式返回的数据成为这个函数的参数?有人能清楚地解释如何从jsonp请求中检索/使用数据吗?

3 个解决方案

#1


40  

The callback is a function YOU'VE defined in your own code. The jsonp server will wrap its response with a function call named the same as your specified callback function.

回调函数是您在自己的代码中定义的函数。jsonp服务器将使用与指定回调函数同名的函数调用来包装它的响应。

What happens it this:

这发生了什么:

1) Your code creates the JSONP request, which results in a new <script> block that looks like this:

1)您的代码创建了JSONP请求,结果是一个新的

<script src="http://server2.example.com/RetrieveUser?UserId=1234&jsonp=parseResponse"></script>

2) That new script tag is executed by your browser, resulting in a request to the JSONP server. It responds with

2)新脚本标记由浏览器执行,从而导致对JSONP服务器的请求。它会用

parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7});

3) Since this request came from a script tag, it's pretty much EXACTLY the same as if you'd literally placed

3)由于这个请求来自一个脚本标记,它几乎与您实际放置的几乎完全相同

<script>
    parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7});
</script>

into your page.

到你的页面。

4) Now that this new script has been loaded from the remote server, it will now be executed, and the only thing it will do is a function call, parseResponse(), passing in the JSON data as the function call's only parameter.

4)既然从远程服务器加载了这个新脚本,现在就可以执行它了,它所要做的惟一事情就是调用parseResponse()函数,将JSON数据作为函数调用的唯一参数传递进来。

So somewhere else in your code, you'd have:

所以在代码中的其他地方,你会有:

function parseResponse(data) {
     alert(data.Name); // outputs 'Foo'
}

Basically, JSONP is a way of bypassing the browser's same-origin script security policy, by having a 3rd party server inject a function call directly into your page. Note that this is by design highly insecure. You're depending that the remote service is honorable and doesn't have malicious intent. Nothing stops a bad service from returning some JS code that steals your banking/facebook/whatever credentials. e.g.... the JSONP response could've been

基本上,JSONP是一种绕过浏览器的同源脚本安全策略的方法,让第三方服务器直接将函数调用注入到页面中。请注意,这是设计高度不安全的。您依赖的是远程服务是高尚的,并且没有恶意意图。没有什么能阻止坏的服务返回一些JS代码,这些代码会窃取您的银行/facebook/任何凭证。如....JSONP的反应可能是

 internalUseOnlyFunction('deleteHarddrive');

rather than parseReponse(...). If the remote site knows the structure of your code, it can perform arbitrary operations with that code, because you've opened your front door wide-open to allow that site to do anything it wants.

而不是parseReponse(……)。如果远程站点知道您的代码的结构,那么它可以使用这些代码执行任意操作,因为您已经打开了前门,允许该站点做它想做的任何事情。

#2


1  

Edit: As Jon said, there is a way better explanation for it here.

编辑:正如Jon所说,这里有一个更好的解释。

JSONP uses script tags to make cross origin requests. Since a script tag is used to include scripts, the server needs to return valid JavaScript. The way we give the JavaScript to the client is through a function call. You tell the server what function you want the script to call, and then you create that function locally. When the script is done loading, your function will be called with the data as a parameter.

JSONP使用脚本标记进行跨源请求。由于脚本标记用于包含脚本,因此服务器需要返回有效的JavaScript。我们向客户端提供JavaScript的方式是通过函数调用。您告诉服务器要调用脚本的函数,然后在本地创建该函数。当脚本加载完成后,将以数据作为参数调用函数。

So if you did a JSONP request at the URL you mentioned, and it returned the payload you mentioned, you would get to your data by doing this:

如果你在你提到的URL上做了一个JSONP请求,它返回了你提到的有效载荷,你可以通过这样做得到你的数据:

function parseResponse(data) {
    console.log("JSONP request complete", data);
}

#3


0  

The function name parseResponse is passed to the server and somehow the data returned becomes parameters to this function

函数名parseResponse被传递给服务器,以某种方式返回的数据成为这个函数的参数

Looks like you just explained it yourself, jsonp=parseResponse is how this app sets the callback function, so it returns a function with your json data in it, that looks like

看起来就像你自己解释的,jsonp=parseResponse是这个应用程序设置回调函数的方式,所以它返回一个带有json数据的函数,看起来是这样的。

parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7});

which is called when it's been loaded and would be handled by a function in your JS like:

加载时调用,由JS中的函数处理:

function parseResponse(data){
    console.log(data);
}

#1


40  

The callback is a function YOU'VE defined in your own code. The jsonp server will wrap its response with a function call named the same as your specified callback function.

回调函数是您在自己的代码中定义的函数。jsonp服务器将使用与指定回调函数同名的函数调用来包装它的响应。

What happens it this:

这发生了什么:

1) Your code creates the JSONP request, which results in a new <script> block that looks like this:

1)您的代码创建了JSONP请求,结果是一个新的

<script src="http://server2.example.com/RetrieveUser?UserId=1234&jsonp=parseResponse"></script>

2) That new script tag is executed by your browser, resulting in a request to the JSONP server. It responds with

2)新脚本标记由浏览器执行,从而导致对JSONP服务器的请求。它会用

parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7});

3) Since this request came from a script tag, it's pretty much EXACTLY the same as if you'd literally placed

3)由于这个请求来自一个脚本标记,它几乎与您实际放置的几乎完全相同

<script>
    parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7});
</script>

into your page.

到你的页面。

4) Now that this new script has been loaded from the remote server, it will now be executed, and the only thing it will do is a function call, parseResponse(), passing in the JSON data as the function call's only parameter.

4)既然从远程服务器加载了这个新脚本,现在就可以执行它了,它所要做的惟一事情就是调用parseResponse()函数,将JSON数据作为函数调用的唯一参数传递进来。

So somewhere else in your code, you'd have:

所以在代码中的其他地方,你会有:

function parseResponse(data) {
     alert(data.Name); // outputs 'Foo'
}

Basically, JSONP is a way of bypassing the browser's same-origin script security policy, by having a 3rd party server inject a function call directly into your page. Note that this is by design highly insecure. You're depending that the remote service is honorable and doesn't have malicious intent. Nothing stops a bad service from returning some JS code that steals your banking/facebook/whatever credentials. e.g.... the JSONP response could've been

基本上,JSONP是一种绕过浏览器的同源脚本安全策略的方法,让第三方服务器直接将函数调用注入到页面中。请注意,这是设计高度不安全的。您依赖的是远程服务是高尚的,并且没有恶意意图。没有什么能阻止坏的服务返回一些JS代码,这些代码会窃取您的银行/facebook/任何凭证。如....JSONP的反应可能是

 internalUseOnlyFunction('deleteHarddrive');

rather than parseReponse(...). If the remote site knows the structure of your code, it can perform arbitrary operations with that code, because you've opened your front door wide-open to allow that site to do anything it wants.

而不是parseReponse(……)。如果远程站点知道您的代码的结构,那么它可以使用这些代码执行任意操作,因为您已经打开了前门,允许该站点做它想做的任何事情。

#2


1  

Edit: As Jon said, there is a way better explanation for it here.

编辑:正如Jon所说,这里有一个更好的解释。

JSONP uses script tags to make cross origin requests. Since a script tag is used to include scripts, the server needs to return valid JavaScript. The way we give the JavaScript to the client is through a function call. You tell the server what function you want the script to call, and then you create that function locally. When the script is done loading, your function will be called with the data as a parameter.

JSONP使用脚本标记进行跨源请求。由于脚本标记用于包含脚本,因此服务器需要返回有效的JavaScript。我们向客户端提供JavaScript的方式是通过函数调用。您告诉服务器要调用脚本的函数,然后在本地创建该函数。当脚本加载完成后,将以数据作为参数调用函数。

So if you did a JSONP request at the URL you mentioned, and it returned the payload you mentioned, you would get to your data by doing this:

如果你在你提到的URL上做了一个JSONP请求,它返回了你提到的有效载荷,你可以通过这样做得到你的数据:

function parseResponse(data) {
    console.log("JSONP request complete", data);
}

#3


0  

The function name parseResponse is passed to the server and somehow the data returned becomes parameters to this function

函数名parseResponse被传递给服务器,以某种方式返回的数据成为这个函数的参数

Looks like you just explained it yourself, jsonp=parseResponse is how this app sets the callback function, so it returns a function with your json data in it, that looks like

看起来就像你自己解释的,jsonp=parseResponse是这个应用程序设置回调函数的方式,所以它返回一个带有json数据的函数,看起来是这样的。

parseResponse({"Name": "Foo", "Id" : 1234, "Rank": 7});

which is called when it's been loaded and would be handled by a function in your JS like:

加载时调用,由JS中的函数处理:

function parseResponse(data){
    console.log(data);
}