格式明智,文件类型明智和实际使用明智?
基本上,由于同源策略,您不允许通过AJAX从另一个域请求JSON数据。AJAX允许您在页面已经加载后获取数据,然后在返回后执行一些代码/调用函数。我们不能使用AJAX,但我们可以将<script>标记注入到我们自己的页面中,这些标记可以引用托管在其他域的脚本。
<script>
通常你会使用它来包括来自CDN的库,比如jQuery。然而,我们可以滥用它,用它来获取数据!JSON已经是有效的JavaScript (大部分情况下),但我们不能只在脚本文件中返回JSON,因为我们无法知道脚本/数据何时完成加载,也无法访问它,除非它被赋值给变量或传递给函数。因此,我们要做的是告诉web服务在它准备好时代表我们调用一个函数。
例如,我们可能会从股票交易所API请求一些数据,并与我们通常的API参数一起,给它一个回调,如?callback=callThisWhenReady。然后,web服务用我们的函数包装数据,并像这样返回:callThisWhenReady({...data...})。现在,一旦脚本加载,您的浏览器将尝试执行它(正常),然后调用我们的任意函数并为我们提供我们想要的数据。
?callback=callThisWhenReady
callThisWhenReady({...data...})
它的工作原理很像普通的AJAX请求,只是我们必须使用命名函数而不是调用匿名函数。
jQuery实际上为您无缝地支持这一点,它为您创建了一个唯一命名的函数并将其传递出去,然后该函数将依次运行您想要的代码。
JSONP本质上是带有额外代码的JSON,就像包裹在数据周围的函数调用。它允许在解析期间对数据进行操作。
JSONP允许您指定传递JSON对象的回调函数。这允许您绕过同源策略,并将JSON从外部服务器加载到网页上的JavaScript中。
JSONP是带填充的JSON。也就是说,在开头放一个字符串,在它周围放一对括号。例如:
//JSON {"name":"stackoverflow","id":5} //JSONP func({"name":"stackoverflow","id":5});
结果是,您可以将JSON作为脚本文件加载。如果你之前设置了一个名为func的函数,那么当脚本文件加载完成时,该函数将被调用一个参数,即JSON数据。这通常用于允许使用JSON数据进行跨站点AJAX。如果您知道example.com提供的JSON文件与上面给出的JSONP示例类似,那么您可以使用如下代码来检索它,即使您不在example.com域中:
func
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);
“JSONP是带有额外代码的JSON”对于现实世界来说太简单了。不,你得有一点出入。如果所有东西都只是工作,编程还有什么乐趣?
结果是JSON不是JavaScript的子集。如果您所做的只是获取一个JSON对象并将其包装在一个函数调用中,总有一天您会被奇怪的语法错误所困扰,就像我今天一样。
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);
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 }
当从客户端发送来自不同域的JSON响应时,JSONP是克服浏览器限制的一种简单方法。
但是,这种方法的实际实施涉及到一些微妙的差异,这些差异往往没有得到清楚的解释。
下面是一个简单的教程,并排展示了JSON和JSONP。
所有的代码都可以在Github上免费获得,并且可以在http://json-jsonp-tutorial.craic.com上找到一个实时版本