2012-04-17 69 views
17

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

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

究竟是什么jsonp = parseResponse实际上是指/?然后他们继续说有效载荷是:

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

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

+0

可能重复[请解释JSONP](http://stackoverflow.com/questions/2067472/please-explain-jsonp) – Jon 2012-04-17 14:27:13

回答

40

回调是一个函数,你'VE在您自己的代码中定义。 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是绕过浏览器的同源脚本安全策略,由具有第三方服务器注入函数调用的方式直接进入你的页面。请注意,这在设计上非常不安全。您认为远程服务是光荣的,并没有恶意的意图。没有什么能够阻止一些糟糕的服务返回一些JS代码来窃取你的银行/脸书/任何凭据。例如...... JSONP响应可能是

internalUseOnlyFunction('deleteHarddrive'); 

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

+8

我不会像'deleteHardDrive'那样举一个例子(javascript无法在浏览器中做到这一点),但绝对值得注意的是,这可能是危险的。 – hitautodestruct 2013-11-12 13:48:37

+1

很好的解释! – FloatingRock 2014-09-19 16:10:59

1

编辑:正如乔恩所说,有一个更好的解释方法here

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

所以,如果你没有在你所提到的URL JSONP请求,并返回你所提到的有效载荷,你会被这样获取您的数据:

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

数据返回如何神奇地成为parseRepsonse函数的参数? – 2012-04-17 14:30:47

+0

@JohnBaum因为服务器创建将被调用的JS代码? – 2012-04-17 15:10:16

0

函数名parseResponse传递到服务器,并以某种方式 返回的数据变为参数,这个功能

看起来你只是你自己解释它,jsonp=parseResponse是这个应用程序是如何设置的回调函数,所以它返回一个FUNC重刑与它的JSON数据,看起来像

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

当它被加载,并会通过函数在JS像处理被称为:

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