前言: 跨域请求是前台开发中经常遇到的场景,但是由于浏览器同源策略,导致A域下普通的http请求没法加载B域下的数据,跨域问题由此产生。但是通过script标签的方式却可以加载非同域下的js,因此可以利用这一特性,进行跨域数据请求。
先看一下跨域导致的问题,测试域分别为 localhost 和 www.icity366.com, 下文分别对应A域和B域,测试文件为A域下的 data.jsp, 我们在A(localhost)域下请求B(www.icity366.com)域下的数据,看一下data.jsp中关键代码:
$.ajax({ url : "http://www.icity366.com:8080/addresslist/test/Data.do?method=getData", data : {callback : "getData"}, //dataType : "json", type : "get", success : function(data){ alert(data); }, error : function(XmlHttpRequest,textStatus,errorThrown){ //debugger; alert(textStatus); } })
结果为alert("error"),浏览器提示跨域:
利用script标签解决跨域
在data.jsp页面中定义好回调方法,
function getData(data){ alert(data.name); }
通过script标签引用js:
<script type="text/javascript" src="http://www.icity366.com:8080/addresslist/test/Data.do?method=getData&callback=getData"></script>
服务器端java代码如下:
String callback = request.getParameter("callback"); Map<String,String> data = new HashMap<String,String>(); data.put("name", "Liyx"); data.put("age", "25"); String dataJson = JsonUtils.convertToString(data);//Map->json response.getWriter().write(callback+"("+dataJson+")");
请求结果:
java端返回 getData({"age":"25","name":"Liyx"}),页面执行getData(),弹出 Liyx, 说明<script>标签可跨域获得数据。
JSONP方式跨域写法
json核心就是:允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。先看一下写法:
var url = "http://www.icity366.com:8080/addresslist/test/Data.do?method=getData&callback=?"; $.getJSON(url,function(data){ alert(data.name); //Liyx })
callback=? 先传递?过去,jquery会自动生成一个全局函数来替换callback=?中的问号,看一下java端的输出,
jQuery171004718876606784761_1411549835461({"age":"25","name":"Liyx"}),长串即为生成的全局函数,该function会自动销毁,并把数据传递到回调方法中。