对 JSONP 请求的工作方式感到困惑

     2023-03-03     264

关键词:

【中文标题】对 JSONP 请求的工作方式感到困惑【英文标题】:Confused on how a JSONP request works 【发布时间】:2012-04-28 21:39:01 【问题描述】:

我无法理解 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 请求中检索/使用数据吗?

【问题讨论】:

Please explain JSONP 的可能重复项 【参考方案1】:

回调是您在自己的代码中定义的函数。 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 是一种绕过浏览器的同源脚本安全策略的方法,方法是让第 3 方服务器将函数调用直接注入您的页面。请注意,这是设计上非常不安全的。您依赖于远程服务是光荣的并且没有恶意。没有什么能阻止糟糕的服务返回一些窃取您的银行/facebook/任何凭据的 JS 代码。例如.... JSONP 响应可能是

 internalUseOnlyFunction('deleteHarddrive');

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

【讨论】:

我不会像deleteHardDrive 那样举个例子(javascript 不能从浏览器中做到这一点),但绝对值得注意的是这可能很危险。【参考方案2】:

编辑:正如乔恩所说,有更好的解释here。

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

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

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

【讨论】:

返回的数据如何神奇地成为parseRepsonse函数的参数? @JohnBaum 因为服务器创建了将被调用的 JS 代码?【参考方案3】:

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

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

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

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

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

【讨论】:

对 struct 在这段代码中的工作方式感到困惑

】对struct在这段代码中的工作方式感到困惑【英文标题】:Confusedabouthowstructworksinthispieceofcode【发布时间】:2015-02-2315:47:59【问题描述】:我正在查看我将要使用的代码here:#include<sys/stat.h>structstatsb;if(stat(pathname,&sb)==0&... 查看详情

我对 git revert 的工作方式感到困惑

】我对gitrevert的工作方式感到困惑【英文标题】:Iamconfusedabouthowgitrevertworks【发布时间】:2019-08-3115:02:19【问题描述】:我想知道发生了什么。我创建了一个HTML文件并在其中放入了一些行thisisfirstlinethisissecondlinethisisthirdlinethisisf... 查看详情

对标志在makefile中的工作方式感到困惑

】对标志在makefile中的工作方式感到困惑【英文标题】:Confusedabouthowflagsworkinmakefile【发布时间】:2015-09-1101:26:59【问题描述】:我有2个文件:main.cpp,其中包括foo.h。我需要一个使用-std=c++11标志编译它们的makefile,但我不知道为... 查看详情

对 PayPal 的服务器端 SDK 感到困惑

...常工作,但不知何故,我的第六感告诉我创建服务器端SDK请求而不是当前客户端。这是我到目前为止所做的:paypal.Buttons(style:layout: 查看详情

对删除分配给结构数组的动态内存感到困惑

...清除。当我对int和dbl使用完全相同的进程时,它可以正常工作并按应有的方式释放内存。我创 查看详情

对标准输入、标准输出和标准错误感到困惑?

...感到很困惑。如果我的理解是正确的,stdin是程序写入其请求以在进程中运行任务的文件,stdout是内核写入其输出的文件,请求它的进程从,stderr是输入所有异常的文件。在打开这些文件以检查这些文件是否确实发生时,我发现似... 查看详情

对故事板和以编程方式推送 ios Objective C 感到困惑

】对故事板和以编程方式推送iosObjectiveC感到困惑【英文标题】:ConfusedaboutstoryboardsandpushingprogrammaticallyiosObjectiveC【发布时间】:2015-04-3009:25:39【问题描述】:我对故事板和以编程方式推送视图之间的关系感到非常困惑。我正在... 查看详情

对 fetchResultController 如何与 MagicalRecord 一起工作感到困惑

】对fetchResultController如何与MagicalRecord一起工作感到困惑【英文标题】:ConfusedabouthowfetchResultControllerworkswithMagicalRecord【发布时间】:2011-09-2906:29:19【问题描述】:我有一个NSOperation子类,这是主要方法:(void)mainNSAutoreleasePool*Pool=[... 查看详情

对 Django ajax 请求中的 JSON 数据和普通数据感到困惑

】对Djangoajax请求中的JSON数据和普通数据感到困惑【英文标题】:ConfusedwithJSONdataandnormaldatainDjangoajaxrequest【发布时间】:2011-09-2704:04:45【问题描述】:我从互联网上阅读了有关JSON的信息,但我仍然没有掌握它。我正在看这篇文... 查看详情

对 CSRF 保护策略感到困惑

...发送,但不以隐藏输入的形式发送。csrf令牌不会因每个请求而更改,但会在会话期间更改。csrf令牌应该多久更改一次?它应该在每个会话或每个请求中更改吗?客户端或服务器应该设置csrf令 查看详情

CSS 媒体查询 - 对重叠和顺序感到困惑

...我遇到了一个问题,由于设计在一系列屏幕宽度上的行为方式,我在设计中断时使用媒体查询进行调整。问题是,不同的元素在不同的宽度上以不同的方式断裂( 查看详情

对启动模式感到困惑

...间】:2021-11-1022:08:38【问题描述】:我制作了一个以两种方式运行的音乐播放器:如果作为普通应用启动,它会继续播放上次关闭时播放的内容,并且应该在后台启动;如果在文件管理器中选择了一个音频文件,它会播放在前台... 查看详情

对循环内的异步块感到困惑

...据,因为我不知道如何准确地使用调度组。我尝试了多种方式。我在这里做错了什么?privatefuncrecognizeText(images:[UIImage])letmyDispatchGroup=DispatchGroup()se 查看详情

对 SwiftUI 中的 @EnvironmentObject 感到困惑

...ntView中的共享对象Userinit。当我从ContentView切换到NameView时工作得很好。但是,从NameView 查看详情

对查询字符串感到非常困惑

...:2017-01-1704:34:48【问题描述】:我正在使用AlamoFire发出API请求。连接到API非常简单,但最大的挑战是查询API。我正在尝试创建一个类似这样的查询字符串:https://api-fxtrade.oanda.com/v3/instruments/USD_CAD/candles?price=B 查看详情

对创建后台计时器的情况感到困惑

...务不可能执行(除了a)如果它在进入后台后向操作系统请求一点额外的时间来完成任务,或者b)如果它使用其中之一3UIBackgroundModes)。但是这个线程正在谈论创建一个后台计时器iOS4Cre 查看详情

对 Tensorflow 中的多层双向 RNN 感到困惑

...已经构建了两个创建多层双向RNN的函数,第一个可以正常工作,但我不确定它的预测,因为它作为单向多层RNN执行。下面是我的实现: 查看详情

对配置脚本和 Makefile.in 感到困惑

...正在学习如何使用autoconf/automake工具链。我似乎对这里的工作流程有一个大致的了解——基本上你有一个configure.ac脚本,它生成一个可执行的configure文件。生成的configure脚本然后由最终用户 查看详情