2.4 另外说明一点,如果在other.js中有函数通过ajax调用8080中的东西,然后引入之后,调用这个函数,也是可以的,但是如果other.js中函数ajax调用8888的东西,引入之后,调用这个函数,同样是跨域的。
3、script实现跨域请求
3.1 简单模拟服务器返回数据
将jsonp/index.jsp改成如下:这里注意引入的other.js的位置,是在函数getResult之后的,如果在它之前的话,会提示函数不存在。js加载顺序是从上开始,在之前调用没创建的,不能成功。注意这里是指引入的js文件,如果是同一个js文件或者当前页面的js中,先执行调用,然后再写函数也是没有问题的,但是如果先执行调用引入js文件中的函数,然后再引入js文件,就会提示函数不存在。
<script type="text/javascript" src="https://www.jb51.net/js/jquery.min.js"></script> <script type="text/javascript"> function jsonp_fun(){ $.ajax({ url:'http://localhost:8888/other/index.jsp', type:'post', dataType:'text', success:function(data){ console.log(data); } }); } function getResult(data){ alert(data.result); } </script> <script type="text/javascript" src="https://localhost:8888/other/js/other.js"></script>
然后other.js
getResult({"result":"this is other domain's data"});
也就是在jsonp/index.jsp页面写好函数,然后引入其他域的js传入参数去调用这个函数,这里的参数你可以先看做是其他域服务器的接口返回的数据。
刷新页面,效果当然是
弹出alert框,this is other domain's data
3.2 模拟接口访问
看到这里,你会不会还是想不懂,上面js弄啥的,传个死的数据,有什么实际意义吗?,其实script的src不仅可以接js的地址,还可以接servlet的地址,也就是http接口地址,所以接下来,懒得写servlet,这里还是写jsp当做接口,在other项目中新建other.jsp页面,内容如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <% String params = request.getParameter("params"); out.println("ajax cross success,the server receive params :"+params); %>
内容很简单,也就是接受一个params的参数,然后返回数据给调用者。
我们在jsonp/index.jsp中加上
<script type="text/javascript" src="http://localhost:8888/other/other.jsp?params=fromjsonp"></script>
看到这个地址,你是不是很熟悉,不熟悉的证明你用servlet用蠢了,jsp也是servlet,流程就是页面一加载的时候,script标签就会去发送请求,然后返回数据。那么我们刷新页面,看看效果。
Uncaught SyntaxError: Unexpected identifier
报错了,如上,然后代码有问题?No,点击错误,你会看到请求的东西也打印出来了,就是提示错误,表示这个东西浏览器不认识,其实是script不认识啦。
还不明白,那么你去页面加上如下内容,你看报不报错!!肯定报错
<script type="text/javascript"> ajax cross success,the server receive params : jsonp_param </script>
那么js不能解析,我们换一种思路,要是我们输出的是JSON字符串或者调用当前页面函数的字符串了,类似于3.1中返回的getResult({“result”:”this is other domain's data”});
所以改造一下,把other.jsp中的内容改成
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <% String params = request.getParameter("params"); //out.println("ajax cross success,the server receive params :"+params); out.println("getResult({'result':'"+params+"'})"); %>
别忘了,之前jsonp/index.jsp中我们定义了,那么加入引用之后,依然记得getResult函数与引入函数的先后顺序问题。
<script type="text/javascript"> function getResult(data){ alert(data.result); } </script> <script type="text/javascript" src="http://localhost:8888/other/other.jsp?params=fromjsonp"></script>
刷新页面,发现大工告成。
至此,大部分原理已经讲完了,还有一个问题,这里服务器返回的是getResult(xxx),其中这里的xxx可以当做是经过接口的很多处理,然后塞进去的值,但是这个getResult这个函数名,调用方与其他域服务器这一方怎么约定这个名字是一致的了,况且很多公司自己做服务的,别的公司的开发人员去调用,难道每个人都去那么公司去约定调用函数的名字?怎么可能,所以有人就想出来了一种解决方案,当然不是我~~,其实也很简单啦,也就是把回调的函数名字也一起传过去不就行了,所以代码如下:
<script type="text/javascript" src="http://localhost:8888/other/other.jsp?params=fromjsonp&callback=getResult"></script>
other.jsp