首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我不明白JSONP和AJAX有什么不同

我不明白JSONP和AJAX有什么不同
EN

Stack Overflow用户
提问于 2012-04-23 23:37:14
回答 3查看 3.3K关注 0票数 10
  1. 我不认为JSONP中的回调函数与AJAX中的成功回调函数有什么不同。
  2. 考虑到#1,我看不出从根本上说它是如何更安全的。
  3. 那么,AJAX唯一的区别是人为的同域约束吗?
  4. 为什么AJAX不能只允许跨域请求;如果这会导致安全漏洞,那么攻击不是只允许XSS作为JSONP请求吗?

困惑,麦克斯

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-04-23 23:50:17

ajax调用是客户端直接向服务器发出的实际HTTP请求。Ajax调用可以是同步的(阻塞直到它们完成)或异步的。由于相同来源的安全保护,只有在目标服务器使用CORS显式允许跨源请求的情况下,ajax调用才能调用来自web页面的同一台服务器。

JSONP调用是一种有趣的<script>标记攻击,它允许跨源通信。在JSONP调用中,客户端创建一个脚本标记,并在上面放置一个带有callback=xxxx查询参数的URL。该脚本请求(通过脚本标记插入)由浏览器发送到外部服务器。浏览器只是认为它在请求一些javascript代码。然后,服务器为该调用创建一些特殊的javascript,在返回时由浏览器执行的javascript中,服务器会对callback=xxxx查询参数中命名的函数进行函数调用。通过通过向该函数传递数据来定义变量,服务器可以将数据传输回客户端。对于JSONP,客户端和服务器必须就JSONP调用的工作方式和数据的定义进行合作。客户端不能对不显式支持JSONP的服务器进行JSONP调用,因为正确类型的JSONP响应必须由服务器构建,否则就无法工作。

因此,这两种交流方式的工作方式完全不同。只有ajax调用可以是同步的。根据<script>标记插入的本质,JSONP调用总是异步的。

在Ajax调用中,响应返回到ajax事件处理程序中。

在JSONP调用中,当返回的Javascript调用您的函数时,响应就会出现。

在某些方面,JSONP是一个绕过跨源安全机制的安全漏洞。但是,您只能调用那些显式地选择支持类似JSONP机制的服务器,因此如果服务器不希望您将其称为跨源机制,则可以通过不支持JSONP来防止它。您不能对这些其他服务器进行常规ajax调用。

浏览器制造商不能真正关闭这个漏洞,因为如果他们这样做了,成千上万的网页将打破这个漏洞,要么已经使用JSONP,要么从其他域加载脚本。例如,在Google或Microsoft CDNs上使用jQuery的网页都会中断,因为浏览器不允许从跨源域下载javascript。

JSONP在很大程度上是作为一种工作而发明的,它能够提出跨来源的请求。但是,由于JSONP需要明确的服务器支持才能工作,所以这并不是真正的安全问题,因为JSONP调用只能对明确决定允许这种类型的跨源调用的服务器进行。JSONP现在的使用要比以前少得多,因为CORS是作为一种更优雅的控制/允许方法而发明的。CORS是跨源资源共享的意思,它为目标服务器提供了一种方法,可以告诉web浏览器允许哪种类型的跨源请求,甚至可以告诉它允许哪个网页域提出这样的请求。它拥有比JSONP更好的控制,现在所有现代浏览器都支持CORS。

下面是一个跨源调用如何导致问题的例子。如果您可以从任何其他网页加载任意网页或进行任意ajax调用,那么假设您已经登录到Yahoo上的webmail界面,因此其他浏览器窗口。这意味着您的cookie被设置为允许来自浏览器的请求从Yahoo获取数据。如果允许其他网页中的javascript向Yahoo发出一个webmail请求(这将自动附加cookie),那么它可以获取所有的webmail数据并将其发送回自己的站点。一个网站可以从任何其他网站删除所有登录数据。所有的网络安全都会被破坏。

但是,按照我们今天的方式,只要Yahoo不支持使用相同的web cookie的JSONP接口,它就不会受到未经授权的JSONP请求的影响。

下面是一些关于跨源ajax的危险以及为什么必须防止它的其他很好的记录:

为什么跨域Ajax是一个安全问题?

为什么不允许跨域AJAX调用?

为什么跨域AJAX请求被标记为“安全风险”?

票数 20
EN

Stack Overflow用户

发布于 2012-04-24 00:05:00

JSONP的回调不是实际的回调。相反,JSONP通过脚本注入工作。例如,如果您想进行JSONP调用,可以将这个脚本元素插入到DOM中:

代码语言:javascript
复制
<script src="http://example.com/ajaxendpoint?jsonp=parseResponse"></script>

服务器的响应如下所示:

代码语言:javascript
复制
parseResponse({"json":"value"});

它将在窗口的全局范围内进行评估。因此,从本质上讲,JSONP就像一个远程exec(),在这里,服务器被告知要创建要执行的字符串。

这与Ajax非常不同:对于JSONP,响应是在脚本的全局范围内计算的;使用XMLHttpRequest,响应是作为字符串接收的,而不是计算的。(而且,JSONP只能与GET一起使用,而AJAX允许任何http方法。)

因此,对于你的第二个问题,“我看不出从根本上来说,它是如何更安全的。”是的,您是对的,JSONP实际上是非常不安全的。服务器可以返回它想要的任何脚本,并向您的浏览器执行它想做的任何事情!

跨域请求是不安全的,因为它们可以用于向另一个域上的页显示有关当前页的信息。

你是对的,任何XSS攻击都可以使用JSONP。CORS的目的并不是防止XSS (如果您的页面上运行了不受信任的脚本,那么无论如何您都会被排除在外)。

票数 2
EN

Stack Overflow用户

发布于 2012-04-23 23:53:20

根本的区别是,由于某种原因,加载位于其他域上的javascript文件(通过脚本标记)是非常好的,但是默认情况下加载其他跨域资源是不可以的。

我同意你的观点,因为这种划分似乎相当武断。在jQuery中,当您执行JSONP调用时,实际上您正在创建一个脚本标记,加载资源,然后jQuery库通过调用该JSONP结果中定义的函数来执行您的脚本。

在我看来,我想不出通过允许跨域AJAX (允许跨域脚本加载)而引入的额外攻击向量,这是一种普遍的做法(jQuery by googleCDN,广告脚本,google,等等)。

来自维基百科

In addition, many legacy cross-domain operations predating JavaScript are not subjected to same-origin checks; one such example is the ability to include scripts across domains, or submit POST forms.

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10289789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档