JSONP原理javascript
JSON和JSONPhtml
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。对于JSON你们应该是很了解了吧,不是很清楚的朋友能够去json.org上了解下,简单易懂。前端
JSONP是JSON with Padding的略称。它是一个非官方的协议,它容许在服务器端集成Scripttags返回至客户端,经过javascriptcallback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。java
JSONP就像是JSON+Padding同样(Padding这里咱们理解为填充),咱们先看下面的小例子而后再详细介绍。ajax
同源策略数据库
在JavaScript中,有一个很重要的安全性限制,被称为“Same-OriginPolicy”(同源策略)。这一策略对于JavaScript代码可以访问的页面内容作了很重要的限制,即JavaScript只能访问与包含它的文档在同一域下的内容。编程
根据这个策略,在baidu.com下的页面中包含的JavaScript代码,不能访问在google.com域名下的页面内容;甚至不一样的子域名之间的页面也不能经过JavaScript代码互相访问。对于Ajax的影响在于,经过XMLHttpRequest实现的Ajax请求,不能向不一样的域提交请求,例如,在abc.example.com下的页面,不能向def.example.com提交Ajax请求,等等。然而,当进行一些比较深刻的前端编程的时候,不可避免地须要进行跨域操做,这时候“同源策略”就显得过于苛刻。json
然而html中有一些元素是不存在跨域问题的如:script,iframe等元素,利用这些元素,就能很好的解决这个问题.跨域
JSONP的实现方式浏览器
利用在页面中建立<script>节点的方法向不一样域提交HTTP请求,这项技术就能够解决跨域提交Ajax请求的问题。
先看一个简单例子
example1.com有这样一个方法
<script type="text/javascript"> //回调函数 function callback(data) { //显示客户信息在A页面上; } </script> //经过加载example2的JS文件来达到函数调用和数据传递 <script type="text/javascript" src="http://example2.com/test.js"></script>
example2.com的test.js内容以下
//回调函数 callback({name:"张三"});
以上这种方法只是一个简单实现缘由的例子,现实中咱们的数据和回调也不会都写死在JS中的,因此咱们要想办法将这些静态的东西动态生成就能够了.只要将example1.com srcipt 地址改成一个能动态生成JS调用方法的服务地址便可.如:
<script type="text/javascript" src="http://example2.com/test.do"></script>
test.do直接返回以下
callback(数据库客户信息的JSON对象);
例子以下:固然对<script type="text/javascript"src="http://example2.com/test.do">的调用,你也能够动态来建立script标签完成,这样就更灵活一些.
倘若要实现一个需求,某个网站a.com上显示的客户信息来自于其它网站b.com,显然经过AJAX请求去取数据是不能作到的,由于存在同源策略.
A网站的前台实现:
<script type="text/javascript"> //回调函数 function displayCustomer(data) { alert(data); //将客户信息显示在A.com的页面上... } window.onload = function(){ //添加<script>标签的方法 function createScript(src){ var script = document.createElement('script'); script.setAttribute("type","text/javascript"); script.src = src; document.body.appendChild(script); } } </script> createScript("http://B.com/search.do?&callback=displayCustomer");
B网站的后台实现:
@Controller public classJsonpRest { @RequestMapping(value = "/test.do",method = RequestMethod.GET) public @ResponseBody Stringlist(HttpServletRequest request) { returnrequest.getParameter("callback")+"({name:'张三',age:18})"; } }
JSONP的优势是:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中均可以运行,不须要XMLHttpRequest或ActiveX的支持;而且在请求完毕后能够经过调用callback的方式回传结果。
JSONP的缺点则是:
1. 它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种状况,不能解决不一样域的两个页面之间如何进行JavaScript调用的问题。
2. 没有关于 JSONP调用的错误处理。若是动态脚本插入有效,就执行调用;若是无效,就静默失败。失败是没有任何提示的。例如,不能从服务器捕捉到404 错误,也不能取消或从新开始请求。不过,等待一段时间尚未响应的话,就不用理它了。
JQUERY对JSONP的支持
从JQery 1.2之后,就开始支持JSONP的调用。JQuery对前台作了很好的处理如自动生成全局回调函数等,但后台还须要开发人员本身实现.
$.getJSON("http://跨域的dns/xxx.do?callback=?",function(json){ // 业务逻辑执行代码 });
请求URL
http://xxx.com/rest.do?callback=jQuery17207481773362960666_1332575486681&_=1393510789026
$.ajax({ url:"http://xxx.com/rest.do", dataType:"jsonp", //必须指定 jsonp : "c", //若不指定则默认为callback jsonpCallback:"test",//若不指定则Jquery本身生成随机的名称 success:function(data){ //业务逻辑执行代码 } });
请求URL http://xxx.com/rest.do?c=test&_=1393510789026
1. 当dataType为JSONP时,JQUERY会为用户生成一个全局函数名称为jsonpCallback参数的值,这个函数内部调用了success方法JQUERY的实现原理及步骤
2. 以GET方式请求目标地址,并在URL中拼接以jsonp参数值为key,以jsonpCallback值为value的参数
3.请求返回回调函数数据
4.触发调用全局的回调函数,在全局函数回调中调用success方法并将数据传递给success方法