jsonp

我们知道,普通的ajax请求存在跨域无权限访问的问题,这是浏览器的安全策略在起作用

index.php:

[php]  view plain  copy
  1. <?php   
  2.     $info = '{  
  3.         "code" : 10,  
  4.         "title" : "jsonp",  
  5.         "name" : "rgy"  
  6.     }';  
  7.   
  8.     echo $info;  
  9. ?>  

test.html中的js代码:

[javascript]  view plain  copy
  1. $.ajax({  
  2.           type: "post",  
  3.           url: "http://localhost/jsonptest/index.php",  
  4.           dataType: "json",  
  5.           success: function(data) {  
  6.               console.log(data);  
  7.           },  
  8.           error: function(data) {  
  9.               console.log("fail");  
  10.           }  
  11.     });  

举个例子,首先test.html与index.php不在同一域中,test.html当访问index.php时:,通常会出现如下图所示的情况:


怎样解决这个问题呢?

这里有两种思路:

第一种是修改服务端代码,为index.php加上header(Access-Control-Allow_Origin:*);允许所有来源的请求访问该资源。

第二种思路就是通过jsonp的方式


下面先介绍第一种方法:

将index.php修改成如下形式:

[php]  view plain  copy
  1. <?php header('Access-Control-Allow-Origin:*'); ?>  
  2.   
  3. <?php   
  4.     $info = '{  
  5.         "code" : 10,  
  6.         "title" : "jsonp",  
  7.         "name" : "rgy"  
  8.     }';  
  9.   
  10.     echo $info;  
  11. ?>  
再通过test.html进行跨域访问就没有问题了,结果如下:



第二种方法:

首先将服务端代码改成如下形式:

[php]  view plain  copy
  1. <?php  
  2.       
  3.     $callback = $_GET['callback'];    
  4.   
  5.     $info = '{"code":10,"title":"jsonp","name":"rgy"}';  
  6.   
  7.     echo $callback."(".$info.")";  
  8.   
  9. ?>  
test.html可以通过如下方式进行访问:

[javascript]  view plain  copy
  1. $.ajax({  
  2.             type: "get",  
  3.             url: "http://todolist6.sinaapp.com/pages/QuickWayGetInfo.php",  
  4.             dataType: "jsonp",  
  5.             jsonp: "callback",  
  6.             success: function(data) {  
  7.                 console.log(data);  
  8.             },  
  9.             error: function() {  
  10.                 console.log("fail");  
  11.             }  
  12. <span style="white-space:pre">    </span>});  
[javascript]  view plain  copy
  1. $.getJSON("http://todolist6.sinaapp.com/pages/QuickWayGetInfo.php?callback=?",function(data){  
  2.             console.log(data);  
  3.         });   
结果如下:



这是用的jquery帮我们封装好的方法,虽然使用起来方便,但是却不利于大家理解jsonp的原理,下面就是原生的js模拟一下jsonp的访问过程

说白了,就是利用src属性能够跨域访问的特性

[javascript]  view plain  copy
  1. var showInfo = function(data){  
  2.      console.log(data);  
  3. }  
  4.   
  5. var url = "http://todolist6.sinaapp.com/pages/QuickWayGetInfo.php?callback=showInfo";  
  6.   
  7. var script = document.createElement('script');  
  8. script.setAttribute('src', url);  
  9. document.getElementsByTagName('head')[0].appendChild(script);  
先定义了一个回调方法showInfo,然后将其当作url参数的一部分发送到服务端,服务端通过字符串拼接的方式将数据包裹在回调方法中,再返回回来

然而这样使用起来相当不方便,在不使用其他js库的情况下,对这个过程进行封装:

[javascript]  view plain  copy
  1. function loadScript(xyUrl, callback){  
  2.     var head = document.getElementsByTagName('head')[0];  
  3.     var script = document.createElement('script');  
  4.     script.type = 'text/javascript';  
  5.     script.src = xyUrl;  
  6.       
  7.     script.onload = script.onreadystatechange = function(){  
  8.         if((!this.readyState || this.readyState === "loaded" || this.readyState === "complete")){  
  9.             callback && callback();  
  10.             // Handle memory leak in IE  
  11.             script.onload = script.onreadystatechange = null;//人工回收内存  
  12.             if ( head && script.parentNode ) {  
  13.                 head.removeChild( script );  
  14.             }  
  15.         }  
  16.     };  
  17.     head.insertBefore( script, head.firstChild );  
  18. }  
  19.   
  20. //  
  21.   
  22. var url = "http://todolist6.sinaapp.com/pages/QuickWayGetInfo.php?callback=showInfo";  
  23.   
  24. loadScript(url, showInfo);  
  25.   
  26. var showInfo = function(data){  
  27.     console.log(data.name);  
  28. }  

总结:

jsonp就是利用<script>标签中src属性能够跨域访问的特性,先定义了一个回调方法,然后将其当作url参数的一部分发送到服务端,服务端通过字符串拼接的方式将数据包裹在回调方法中,再返回回来


ajax和jsonp其实本质上是不同的东西,虽然jquery将其整合在了一块儿,ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本


jsonp是一种非强制性协议,或者说它更像是一种方法,如同ajax一样,它也不一定非要用json格式来传递数据,只要返回是内容是可执行的js脚本就行了


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值