标签:
最近做一个项目需要在客户端去第三方供应商服务器获取数据,第一想到的方法就是通过ajax的方式发送请求获取数据。由于我们的系统和第三方系统不在一个域,因此通过ajax发送请求就碰到了跨域的问题。
在网上查找了一些方法,发现一般解决跨域问题就是两种方式:一是通过ajax在服务端通过代理的方式实现;二是通过jsonp的方式。
经过两种方式比较,最终选择了第二种方式实现了跨域请求。下面结合本次需求的经历简单总结一下JSONP的方式。
我们都知道ajax直接请求普通文件都存在跨域无权限访问的问题,但是Web页面上调用JS文件不受是否跨域的影响,于是就可以想象到,如果在远程服务器端设法将数据装进JS格式的文件里,那么客户端就可以获取到,并不受跨域的影响。这就是JSONP基本的实现原理。
下面举例说明:
1、本地有一个html文件a.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <script type="text/javascript"> var localHandler = function(data){ alert(‘我是本地函数,可以被跨域的b.js文件调用,远程js带来的数据是:‘ + data.result); }; </script> <script type="text/javascript" src="http://test.com/b.js"></script> </head> <body> </body> </html>
2、远程服务器test.com根目录有一个b.js文件
localHandler({"result":"跨域测试"})
运行本地的html文件,发现成功弹出提示框,并且成功接收到服务器test.com带来的js数据。
以上就是一个基本的JSOP跨域请求的例子。
但是在实际开发过程中JSONP的服务者面对很多的服务对象,每个服务对象各自本地的函数都不相同,那么他们是怎么调用的呢?
解决方式很简单,就是在客户端请求服务器时,在url中传一个callback参数,callback参数传递的是本地客户端需要回调的函数名称。服务端根据这个callback参数动态生生成js脚本供客户端进行调用。
例如,请求http:test.com/c.aspx?callback=funCallBack这样一个服务地址,c.aspx页面根据callback参数内容,向客户端返回以下js字符串
funCallBack({"result":"******"})
这样客户端就能顺利调用funCallBack函数。
JSONP基本原理就是这样,其实很简单。我们日常使用的js框架,像jQuery,就在ajax中对JSONP进行了非常好的封装,
们这次就是结合jQuery和JSONP解决的跨域问题。(ajax和jsonp两种技术在调用方式相似,都是通过请求url,然后对服务器返回的数据进行处理,因此jquery和ext等很多框架都喜欢把jsonp座位ajax的形式进行封装。实际他们本质还是有区别的,ajax核心是通过XmlHttpRequest获取内容,而jsonp核心是通过动态添加<script>标签来调用服务器提供的js脚本)
1、客户端代码如下
<!DOCTYPE html> <html> <head> <title></title> <script type="text/javascript" src="js/jquery-2.1.4.js"></script> <script type="text/javascript"> function doTest(){ $.ajax({ type:"Get", url :"test1.php?user=admin&password=123", dataType:"jsonp", jsonp:"callback",//传递给请求服务器处理程序或页面的,用以获得JSONP回调函数名 jsonpCallback:"jsonCallBackTest",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,此属性可不配置 success:function(data){ alert(data.user+" "+data.password); }, error:function(){ alert("error"); } }); } function jsonCallBackTest(data){ alert("jsoncallback"+data.user+" "+data.password); } </script> </head> <body> <button onclick="doTest()">button</button> </body> </html>
2、服务器代码
<?php /** * Created by PhpStorm. * User: zhoufy * Date: 15/11/26 * Time: 21:22 */ header(‘Content-Type:text/html;Charset=utf-8‘); $arr = array( "user"=>$_GET["user"], "password"=>$_GET["password"] ); echo $_GET[‘callback‘]."(".json_encode($arr).")";//此处的callback需要和客户端ajax请求中的jsonp属性保持一致。
运行test1.html,发现成功执行了jsonCallBackTest方法,然后又执行了success属性方法。
执行jsonCallBackTest方法可以理解,是因为在jquery的ajax访问中设置了jsonpCallback属性,因此会触发对应的回调函数。
那么怎么success属性方法也会被执行呢?其实这是jquery的封装,jquery在处理jsonp类型的ajax时,自动生成回调函数并把数据取出来供success属性方法调用。
好了,写到这里相信大家对jquery的jsonp处理跨域请求有了一定了解吧!第一次在博客园写博客,希望看到的朋友多多提意见和问题,谢谢!
标签:
原文地址:http://www.cnblogs.com/zhoufy/p/4999411.html