跨域知识——JSONP
Posted baoyadong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了跨域知识——JSONP相关的知识,希望对你有一定的参考价值。
JSONP是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持,服务器改造非常小。
它的基本思想是,网页通过添加一个<script>
元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
如果对于callback参数如何使用还有些模糊的话,我们后面会有具体的实例来讲解。
首先,网页动态插入<script>
元素,由它向跨源网址发出请求。
1 <h1>绕过浏览器禁止跨域请求的方案之八——JSONP</h1> 2 <button id="bt1">请求数据</button> 3 <script src="jquery-1.11.3.js"></script> 4 <script> 5 //声明静态函数 —— 客户端不直接调用 6 function doRes(data){ 7 console.log(\'开始处理服务器端返回的数据\') 8 console.log(data); 9 } 10 11 12 $(\'#bt1\').click(function(){ 13 //动态创建一个SCRIPT标签,添加到DOM 14 var s = document.createElement(\'script\'); 15 s.setAttribute(\'async\', \'true\'); //脚本异步执行 16 s.src = \'http://localhost/crossdomain/4.php?callback=doRes\'; 17 document.body.appendChild(s); 18 //OM树上追加了新的SCRIPT,浏览器就 19 //会立即请求该资源并执行服务器返回的JS 20 21 })
上面代码通过动态添加<script>
元素,向服务器http://localhost/crossdomain/4.php发出请求。
注意,该请求的查询字符串有一个callback
参数,用来指定回调函数的名字,这对于JSONP是必需的。
2.基于jquery的跨域
jquery发起跨域请求,有两种方法:
(1)$.getJSON()
XHR非跨域请求:
$.getJSON(\'x.php\', function(){})
SCRIPT实现JSONP请求
$.getJSON(\'跨域地址/x.php?callback=?\', function(){})
(2)$.ajax()
XHR非跨域请求:
$.ajax({....})
SCRIPT实现JSONP请求:
$.ajax({
url: \'跨域地址/x.php\',
dataType:\'jsonp\',
success: function(){ ... }
})
demo1如下:
1 <h1>jQuery.getJSON与跨域请求</h1> 2 <button id="bt1">请求数据(非跨域)</button> 3 <button id="bt2">请求数据(跨域)</button> 4 <script src="jquery-1.11.3.js"></script> 5 <script> 6 $(\'#bt1\').click(function(){ 7 //XHR非跨域 8 $.getJSON(\'5-1.php\', function(data){ 9 console.log(\'1 处理服务器返回的数据\') 10 console.log(data); 11 }) 12 }); 13 14 $(\'#bt2\').click(function(){ 15 //XHR跨域 —— 浏览器禁止 16 // $.getJSON(\'http://localhost/crossdomain/5-1.php?\', function(data){ 17 // console.log(\'2 处理服务器返回的数据\') 18 // console.log(data); 19 // }) 20 21 $.getJSON(\'http://localhost/crossdomain/5-2.php?callback=?\',function(data){ 22 console.log(\'3 处理服务器返回的数据\') 23 console.log(data); 24 }) 25 });
jquery在处理jsonp类型的ajax时(还是忍不住吐槽,虽然jquery也把jsonp归入了ajax,但其实它们真的不是一回事儿),自动帮
你生成回调函数并把数据取出来供success属性方法来调用。
在服务器端,代码如下:
1 <?php 2 //header(\'Content-Type: application/json\'); 3 header(\'Content-Type: application/javascript\'); 4 sleep(10); //让当前解释器暂停执行10s 5 $cb = $_REQUEST[\'callback\']; 6 $data = [ 7 \'ename\'=>\'Tom\', 8 \'age\'=>20 9 ]; 10 echo $cb. \'(\' .json_encode($data) . \')\';
demo2如下:
<h1>jQuery.ajax与跨域请求</h1> <button id="bt1">请求数据(非跨域)</button> <button id="bt2">请求数据(跨域)</button> <script src="jquery-1.11.3.js"></script> <script> $(\'#bt1\').click(function(){ //XHR非跨域 $.ajax({ url: \'6-1.php\', success: function(){} }) }); $(\'#bt2\').click(function(){ $.ajax({ url: \'http://localhost/crossdomain/6-2.php\', dataType: \'jsonp\', //指定响应消息的数据类型 success: function(data){ console.log(\'4 开始处理响应数据\') console.log(data); } }); });
以上是关于跨域知识——JSONP的主要内容,如果未能解决你的问题,请参考以下文章