对JSONP请求的工作原理感到困惑

时间:2012-04-17 14:22:37

标签: javascript ajax jsonp

我无法理解jsonp请求的工作原理。我已经阅读了几个来源,包括jsonp上的wiki,并且仍然非常困惑于回调实际上如何在进行jsonp调用时保持从服务器返回的函数。例如,在wiki中,请求的来源设置为:

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

jsonp = parseResponse究竟是做什么/意味着什么?然后他们继续说有效载荷是:

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

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

3 个答案:

答案 0 :(得分:43)

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

这是怎么回事:

1)您的代码会创建JSONP请求,从而生成一个新的<script>块,如下所示:

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

2)浏览器执行新脚本标记,从而向JSONP服务器发出请求。它以

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

3)因为这个请求来自一个脚本标签,所以它几乎就像你真正放置一样

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

进入你的页面。

4)现在已经从远程服务器加载了这个新脚本,它现在将被执行,它唯一要做的就是函数调用parseResponse(),传入JSON数据作为函数呼叫的唯一参数。

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

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

基本上,JSONP是一种绕过浏览器的同源脚本安全策略的方法,让第三方服务器直接向您的页面注入函数调用。请注意,这在设计上非常不安全。您依赖于远程服务是光荣的并且没有恶意。没有什么可以阻止糟糕的服务返回一些窃取你的银行/ Facebook /任何凭据的JS代码。例如...... JSONP响应可能已经

 internalUseOnlyFunction('deleteHarddrive');

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

答案 1 :(得分:1)

编辑:正如Jon所说,有一种更好的解释方法here

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

因此,如果您在您提到的URL处执行了JSONP请求,并且它返回了您提到的有效负载,那么您将通过执行以下操作来获取数据:

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

答案 2 :(得分:0)

  

函数名称parseResponse以某种方式传递给服务器   返回的数据成为此函数的参数

看起来你刚才自己解释过,jsonp=parseResponse这个应用程序是如何设置回调函数的,所以它返回一个包含json数据的函数,看起来像

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

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

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