困惑于JSONP请求的工作方式是什么?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (19)

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

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

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

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

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

提问于
用户回答回答于

回调函数是在自己的代码中定义的函数。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(...)。如果远程站点知道你的代码的结构,它可以使用该代码执行任意操作,因为你已经打开了前门,允许该站点执行任何想要的操作。

用户回答回答于

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

所以如果你在你提到的URL上做了一个JSONP请求,并且它返回了你提到的有效负载,你可以这样做:

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

扫码关注云+社区