主要参考文章:http://www.cnblogs.com/wangfupeng1988/p/4060747.html
项目是分布式的,跨域是个绕不过去的坎,分2种方式:
1、服务器端跨域httpclient很多例子了。这里就不谈了。
2、客户端跨域(主要解释)
客户端的跨域,在服务器代码没有声明的前提下直接访问是会报错的。No 'Access-Control-Allow-Origin
但是浏览器会引入其他域的js文件,所以一个想法诞生了:
一 、 其他域的js文件代码http://localhost/source.js
xhrHandler({"id":"123"});
调用页面代码localhost:8080/test.html
xhrHandler(data){
alert(data.id);
}
<script language="javascript" src="http://localhost/source.js">
从域名可以看出来端口号变化了,可以依然能引入source.js,那么上面的代码相当于:
function xhrHandler(data){
alert(data.id);
}
xhrHandler({"id":"123"});
是的,相当于声明了xhrHandler方法,又执行了这个方法。
二、下来思路就成了,如何将想请求的Controller生成一个js,就可以绕过浏览器了。
下来的Controller代码:
@RequestMapping(value="/test",method=RequestMethod.GET) @ResponseBody public String test(HttpServletRequest request, HttpServletResponse response){ String callback = request.getParameter("callback"); if(callback != null){ return callback + "({'id':'123'})"; }else{ return "error"; } }
调用的js代码:
function test(){
addScriptTag("http://localhost:81/search/epinfo/test?callback=xhrHandle");
}
function xhrHandle(data){
alert(data.id);
}
function addScriptTag(src) {
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.src = src;
document.body.appendChild(script);
}
当test()方法执行,调用addScriptTag()方法,发送地址,请求了一个跨域页面,
然后构造了一个<script type=text/javascript src=****></script>的js引用。
在服务器端返回了一个xhrHandle(json)的字符串。上面的代码相当于
function xhrHandle(data){
alert(data.id);
}
xhrHandle(服务器端需要传值的json对象);
所有操作只为了一个目的-----传值,分成2步
1、在服务器端返回字符串xhrHandle(data);
2、在客户端构造<script language="javascript" >xhrHandle(data);</script>
这就是JSONP,和ajax,和json没关系!没关系!没关系!重要的事情说三遍!
三、下来试试jquery方式
jquery方式调用,更简单,也更类似ajax方式,他只是将上面的方法进行包装
默认的有一个callback参数,你申请的页面就成了http://ip:port/***?callback=随机生成的一个乱七八糟的方法名
用谷歌控制台可以明显看出来申请地址的变化,实例如下:
function test(){
$.ajax({
url: "http://localhost:81/search/epinfo/test",//?callback=xhrHandle",
type: 'GET',
dataType: 'JSONP',//here
success: function(data) {
alert(data.id);
}
});
}
是不是很像ajax?可惜和ajax没关系,-_-!!
更进一步,如果想自定义回调函数名,应该这样:
客户端
function test(){
$.ajax({
url: "http://localhost:81/search/epinfo/test",//?callback=xhrHandle",
type: 'GET',
dataType: 'JSONP',//here
jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(默认为:callback)
jsonpCallback:"success_jsonpCallback",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名
});
}
function success_jsonpCallback(data){
alert(data.id);
}
服务器端:
@RequestMapping(value="/test",method=RequestMethod.GET)
@ResponseBody
public String test(HttpServletRequest request, HttpServletResponse response){
String callback = request.getParameter("callback");
if(callback != null){
return callback + "({'id':'123'})";
}else{
return "error";
}
}
jquery只是封装了一下,自动生成了一个回调函数,并且在success后执行。
收工~!