格式明智,文件类型明智和实际使用明智?
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 (for the most part),但我们不能只在脚本文件中返回 JSON,因为我们无法知道脚本/数据何时完成加载,并且除非已分配,否则我们无法访问它到变量或传递给函数。因此,我们要做的是告诉 Web 服务在它准备好时代表我们调用一个函数。
例如,我们可能会从证券交易所 API 请求一些数据,并且连同我们常用的 API 参数一起,我们给它一个回调,例如 ?callback=callThisWhenReady
。然后 Web 服务用我们的函数包装数据并像这样返回它: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 和我们围绕 JSON 内容创建的回调函数通过 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)
当从客户端发送来自不同域的 JSON 响应时,JSONP 是一种克服浏览器限制的简单方法。
客户端使用 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 is not a subset of JavaScript。如果你所做的只是获取一个 JSON 对象并将其包装在一个函数调用中,那么有一天你会被奇怪的语法错误所困扰,就像我今天一样。
当从客户端发送来自不同域的 JSON 响应时,JSONP 是一种克服浏览器限制的简单方法。
但该方法的实际实施涉及到通常无法清楚解释的细微差异。
这是一个简单的教程,它并排显示 JSON 和 JSONP。
所有代码均可在 Github 上免费获得,实时版本可在 http://json-jsonp-tutorial.craic.com 找到