在格式、文件类型和实际使用方面,有何不同?
在格式、文件类型和实际使用方面,有何不同?
JSONP是带有填充的JSON。也就是说,你在开头放置一个字符串,然后用括号把它括起来。例如:
//JSON
{"name":"stackoverflow","id":5}
//JSONP
func({"name":"stackoverflow","id":5});
结果是您可以将JSON作为脚本文件加载。如果您之前设置了一个名为func
的函数,那么当脚本文件加载完成时,该函数将使用一个参数(即JSON数据)进行调用。这通常用于允许跨站点使用JSON数据的AJAX。如果您知道example.com正在提供类似于上面给出的JSONP示例的JSON文件,则可以使用以下代码检索它,即使您不在example.com域上也可以:
function func(json){
alert(json.name);
}
var elm = document.createElement("script");
elm.setAttribute("type", "text/javascript");
elm.src = "http://example.com/jsonp";
document.body.appendChild(elm);
基本上,由于同源策略,您无法通过AJAX从另一个域请求JSON数据。AJAX允许您在页面加载后获取数据,然后一旦返回数据就执行一些代码/调用函数。我们不能使用AJAX,但是可以将<script>
标签注入到我们自己的页面中,并且这些标签允许引用托管在其他域上的脚本。
通常,您会使用CDN(如jQuery)包含库。然而,我们可以滥用此技术来获取数据!JSON已经是有效的JavaScript(大部分情况下是这样),但是我们不能直接在脚本文件中返回JSON,因为我们没有办法知道脚本/数据何时加载完成,也没有办法访问它,除非将其分配给变量或传递给函数。因此,我们告诉网络服务,在准备好时代表我们调用一个函数。
例如,我们可能会从股票交易API请求一些数据,并且除了通常的API参数外,我们还提供了一个回调,例如?callback=callThisWhenReady
。网络服务然后使用我们的函数包装数据,并像这样返回: callThisWhenReady({...data...})
。现在脚本加载后,您的浏览器将尝试执行它(与正常情况一样),这将调用我们的任意函数并提供所需的数据。
它与正常的AJAX请求非常相似,只是不是调用匿名函数,而是必须使用命名函数。
jQuery通过为您创建唯一命名的函数并将其传递,以便无缝支持此功能,然后将运行您想要的代码。
JSONP代表“带填充的JSON”,它是解决从不同域加载数据的方法。它将脚本加载到DOM头部,因此您可以像在自己的域上加载信息一样访问信息,从而绕过跨域问题。
jsonCallback(
{
"sites":
[
{
"siteName": "JQUERY4U",
"domainName": "http://www.jquery4u.com",
"description": "#1 jQuery Blog for your Daily News, Plugins, Tuts/Tips & Code Snippets."
},
{
"siteName": "BLOGOOLA",
"domainName": "http://www.blogoola.com",
"description": "Expose your blog to millions and increase your audience."
},
{
"siteName": "PHPSCRIPTS4U",
"domainName": "http://www.phpscripts4u.com",
"description": "The Blog of Enthusiastic PHP Scripters"
}
]
});
(function($) {
var url = 'http://www.jquery4u.com/scripts/jquery4u-sites.json?callback=?';
$.ajax({
type: 'GET',
url: url,
async: false,
jsonpCallback: 'jsonCallback',
contentType: "application/json",
dataType: 'jsonp',
success: function(json) {
console.dir(json.sites);
},
error: function(e) {
console.log(e.message);
}
});
})(jQuery);
现在,我们可以通过使用JSONP和我们创建的回调函数来通过AJAX请求JSON。输出应该是JSON作为对象,然后我们可以自由地使用数据而没有任何限制。JSONP本质上是带有额外代码的JSON,就像一个函数调用包裹在数据周围。它允许在解析期间对数据进行操作。
JSON
JSON(JavaScript对象表示法)是在应用程序之间传输数据的方便方法,尤其是当目的地是JavaScript应用程序时。
示例:
这是一个使用JSON作为服务器响应传输的最简示例。客户端使用jQuery简写函数$.getJSON进行Ajax请求。服务器生成哈希值,将其格式化为JSON并将其返回给客户端。客户端将其格式化并放入页面元素中。
服务器:
get '/json' do
content_type :json
content = { :response => 'Sent via JSON',
:timestamp => Time.now,
:random => rand(10000) }
content.to_json
end
客户:
var url = host_prefix + '/json';
$.getJSON(url, function(json){
$("#json-response").html(JSON.stringify(json, null, 2));
});
输出:
{
"response": "Sent via JSON",
"timestamp": "2014-06-18 09:49:01 +0000",
"random": 6074
}
JSONP(带填充的 JSON)
JSONP 是在客户端从不同域向服务器发送 JSON 响应时,克服浏览器限制的简单方法。
在客户端使用 JSONP 的唯一变化是将回调参数添加到 URL 中。
服务器:
get '/jsonp' do
callback = params['callback']
content_type :js
content = { :response => 'Sent via JSONP',
:timestamp => Time.now,
:random => rand(10000) }
"#{callback}(#{content.to_json})"
end
客户:
var url = host_prefix + '/jsonp?callback=?';
$.getJSON(url, function(jsonp){
$("#jsonp-response").html(JSON.stringify(jsonp, null, 2));
});
输出:
{
"response": "Sent via JSONP",
"timestamp": "2014-06-18 09:50:15 +0000",
"random": 364
}
JSONP是在客户端从不同域发送JSON响应时克服浏览器限制的简单方法。
但是,这种方法的实际实现涉及微妙的差异,通常没有清楚地解释。
这里有一个简单的教程,展示了JSON和JSONP并排的效果。
所有代码都可在Github上自由获取,live版本可在http://json-jsonp-tutorial.craic.com找到。