一个众所周知的问题,Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面、动态网页、web服务、WCF,只要是跨域请求,一律不准。
不过我们又发现,Web页面上调用js文件时则不受是否跨域的影响(不仅如此,我们还发现凡是拥有”src”这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>)。
JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。
简单的说,jsonp就是通过script标签、src属性和callback回调来实现跨域的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>jsonp test</title> <script> function jsonptest(data) { alert('我的名字叫:' + data.name + ',今年' + data.age + '岁了!'); } </script> <script src="http://www.test.com/jsonp.php?id=1&callback=jsonptest"></script> </head> <body> </body> </html> |
1 2 3 4 5 6 7 8 9 |
<?php $arr = array( array('name' => '张三', 'age' => 20), array('name' => '李四', 'age' => 21), array('name' => '王五', 'age' => 22) ); $callback = $_REQUEST['callback']; $id = $_REQUEST['id']; echo $callback . '(' . json_encode($arr[$id]) . ');'; |
jquery把jsonp封装到了ajax里面,但是我们要知道,jsonp跟ajax其实是两回事。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>jsonp jquery test</title> <script type="text/javascript" src="./jquery.js"></script> <script> $(function(){ $.ajax({ type: "get", async: false, url: "http://www.test.com/jsonp.php?id=2", dataType: "jsonp", jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback) jsonpCallback: "jsonptest",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据 success: function(data){ alert('我的名字叫:' + data.name + ',今年' + data.age + '岁了!'); }, error: function(){ alert('fail'); } }); }); </script> </head> <body> </body> </html> |
ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。
所以说,其实ajax与jsonp的区别不在于是否跨域,ajax通过服务端代理一样可以实现跨域,jsonp本身也不排斥同域的数据的获取。
还有就是,jsonp是一种方式或者说非强制性协议,如同ajax一样,它也不一定非要用json格式来传递数据,如果你愿意,字符串都行,只不过这样不利于用jsonp提供公开服务。
本文参考:http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html