我理解JSON,但不了解JSONP . Wikipedia's document on JSON是(曾)JSONP的热门搜索结果 . 它说:
JSONP或“带填充的JSON”是JSON扩展,其中前缀被指定为调用本身的输入参数 .
咦?什么电话?这对我没有任何意义 . JSON是一种数据格式 . 没有电话 .
2nd search result来自一个名为Remy的人,他写了关于JSONP的文章:
JSONP是脚本标记注入,将响应从服务器传递到用户指定的函数 .
我可以理解这一点,但它仍然没有任何意义 .
那么什么是JSONP?它为什么被创建(它解决了什么问题)?我为什么要用呢?
Addendum :我刚刚在维基百科上创建了a new page for JSONP;它现在根据_90605的答案对JSONP进行了清晰而全面的描述 .
8 回答
因为您可以要求服务器将前缀附加到返回的JSON对象 . 例如
function_prefix(json_object);
为了使浏览器以
eval
"inline"将JSON字符串作为表达式 . 这个技巧使服务器可以直接在客户端浏览器中使用"inject" javascript代码,并绕过"same origin"限制 .换句话说,你可以拥有 cross-domain data exchange .
通常,
XMLHttpRequest
不允许直接进行跨域数据交换(一个需要通过同一域中的服务器),而:<script src="some_other_domain/some_data.js&prefix=function_prefix
>`可以从不同于原点的域访问数据 .另外值得注意的是:即使在尝试那种"trick"之前服务器应被视为"trusted",也可以包含对象格式等可能发生变化的副作用 . 如果使用
function_prefix
(即正确的js函数)来接收JSON对象,则所述函数可以在接受/进一步处理返回的数据之前执行检查 .在了解JSONP之前,您需要了解JSON格式和XML . 目前,Web上最常用的数据格式是XML,但XML非常复杂 . 它使用户不方便处理嵌入在网页中的内容 .
为了使JavaScript能够轻松交换数据,即使作为数据处理程序,我们也会根据JavaScript对象使用措辞并开发出简单的数据交换格式,即JSON . JSON可以用作数据,也可以用作JavaScript程序 .
JSON可以直接嵌入到JavaScript中,使用它们可以直接执行某些JSON程序,但由于安全限制,浏览器Sandbox机制会禁用跨域JSON代码执行 .
为了使JSON可以在执行后传递,我们开发了一个JSONP . JSONP通过JavaScript回调功能和<script>标记绕过了浏览器的安全限制 .
简而言之,它解释了JSONP是什么,它解决了什么问题(何时使用它) .
JSONP是解决跨域脚本错误的绝佳选择 . 您可以完全使用JS来使用JSONP服务,而无需在服务器端实现AJAX代理 .
您可以使用b1t.co服务查看其工作原理 . 这是一个免费的JSONP服务,可以帮助您缩小URL . 以下是用于服务的URL:
http://b1t.co/Site/api/External/MakeUrlWithGet?callback=[resultsCallBack]&url=[escapedUrlToMinify]
例如,电话,http://b1t.co/Site/api/External/MakeUrlWithGet?callback=whateverJavascriptName&url=google.com
会回来的
因此当这个get作为src加载到你的js中时,它会自动运行你应该实现的任何JavascriptName作为你的回调函数:
要实际进行JSONP调用,可以通过多种方式(包括使用jQuery)来实现,但这里是一个纯JS示例:
有关实践的分步示例和jsonp Web服务,请访问:this post
它实际上并不太复杂......
假设您在域example.com上,并且您想向域example.net发出请求 . 要做到这一点,你需要跨越域边界,在大多数浏览器领域都是禁忌 .
绕过此限制的一项是<script>标记 . 当您使用脚本标记时,域限制将被忽略,但在正常情况下,您无法真正获得结果,只会对脚本进行评估 .
输入JSONP . 当您向启用了JSONP的服务器发出请求时,您会传递一个特殊参数,告诉服务器一些关于您的页面的信息 . 这样,服务器就能够以您的页面可以处理的方式很好地包装其响应 .
例如,假设服务器需要一个名为“callback”的参数来启用其JSONP功能 . 然后你的请求看起来像:
如果没有JSONP,这可能会返回一些基本的JavaScript对象,如下所示:
但是,使用JSONP时,当服务器收到“callback”参数时,它会以稍微不同的方式包装结果,返回如下内容:
如您所见,它现在将调用您指定的方法 . 因此,在您的页面中,您定义了回调函数:
现在,当加载脚本时,它将被评估,并且您的函数将被执行 . Voila,跨域请求!
值得注意的是JSONP的一个主要问题:您失去了对请求的大量控制权 . 例如,没有"nice"方法来获取正确的故障代码 . 结果,您最终使用计时器来监视请求等,这总是有点怀疑 . JSONRequest的提议是一个很好的解决方案,允许跨域脚本编写,维护安全性,并允许适当控制请求 .
这些天(2015年),CORS是推荐的方法与JSONRequest . JSONP对于较旧的浏览器支持仍然有用,但鉴于安全隐患,除非您没有选择,否则CORS是更好的选择 .
JSONP 实际上是一个克服 XMLHttpRequest 相同域策略的简单技巧 . (如您所知,无法将 AJAX (XMLHttpRequest) 请求发送到其他域 . )
所以 - 我们必须使用 script HTML标签,而不是使用 XMLHttpRequest 标签,这些标签通常用于加载js文件,以便js从另一个域获取数据 . 听起来怪怪的?
事情是 - 结果 script 标签可用于a时尚类似于 XMLHttpRequest !看一下这个:
在加载数据后,您将得到一个如下所示的 script 段:
但是这有点不方便,因为我们必须从 script 标签中获取此数组 . 所以 JSONP 创作者认为这会更好(并且是):
注意那边的 my_callback 功能?所以 - 当 JSONP 服务器收到你的请求并找到回调参数 - 而不是返回普通的js数组时,它将返回:
See where the profit is: 现在我们得到自动回调(my_callback),一旦我们获得数据就会被触发 .
这就是 JSONP 的全部知识:它是一个回调和脚本标签 .
NOTE: these are simple examples of JSONP usage, these are not production ready scripts.
Basic JavaScript example (simple Twitter feed using JSONP)
Basic jQuery example (simple Twitter feed using JSONP)
JSONP 代表 JSON with Padding . (技术名称很差,因为它与大多数人认为的“填充”无关 . )
一个使用JSONP的简单示例 .
client.html
server.php
JSONP通过构造“脚本”元素(在HTML标记中或通过JavaScript插入DOM)来工作,该元素请求远程数据服务位置 . 响应是一个javascript加载到您的浏览器上,其中包含预定义函数的名称以及传递的参数,即请求的JSON数据 . 当脚本执行时,该函数与JSON数据一起被调用,允许请求页面接收和处理数据 .
For Further Reading Visit: https://blogs.sap.com/2013/07/15/secret-behind-jsonp/
client side snippet of code
Server side piece of PHP code
已经给出了很好的答案,我只需要在javascript中以代码块的形式提供我的文章(我还将包括更多现代和更好的跨源请求解决方案:带有HTTP标头的CORS):
JSONP:
1.client_jsonp.js
2.server_jsonp.js
CORS :
3.client_cors.js
4.server_cors.js