众所周知,Ajax是通过创建XMLHttpRequest对象或ActiveXObject来连接服务器、发送请求以及响应数据,但它却不能跨域。而在分布式系统中我们又需要跨域发送接受数据,于是jsonp出现了...
它是一种跨域请求方式,主要利用了script标签里的src属性,该属性可以跨域发送请求,然后服务器返回js代码,网页端便响应其信息,然后我们可以对其传过来的js代码做处理提取其中的信息。
jsonp发送请求只需在src后面添加“?callback=函数名”就可以,例如“http://www.item.com/list?callback=myfunction",则只需在服务端接受参数myfunction并将函数名与想要返回的数据拼接就可以例如在java中响应该请求,可以获取参数callback的值myfunction,再拼接成myfunction+"("+data+")"格式返回就行,在前端写同名函数接受data并处理就可以了。但在jquery中对jsonp进行了封装,返回函数就是success,数据也用success接受。
例如:
前端代码:
//发送请求
$.ajax({
// url:"http://localhost:8081/rest/itemcat/list?callback=getMessage",
url:"http://localhost:8081/rest/itemcat/message",
type:"get",
cache:false,
dataType:"jsonp",
jsonp:"callback", //这里定义了callback的参数名称,以便服务获取callback的函数名即getMessage
jsonpCallback:"getMessage", //这里定义了jsonp的回调函数
success:function(data){
alert("success:"+data);
},
error:function(){
alert("发生异常");
}
});
function getMessage(jsonp){
alert("message:"+jsonp);
}
这样发出的请求为:http://localhost:8081/rest/itemcat/message?callback=getMessage
jsonp:"callback",
jsonpCallback:"getMessage",
返回函数则变为了success而不是getMessage
服务端:
@RequestMapping(value="/itemcat/message",produces=MediaType.APPLICATION_JSON_VALUE+";charset=utf-8") @ResponseBody public Object getMessage(String callback){ System.out.println(callback); String message="{'name':'盖伦','age':'30'}"; //MappingJacksonValue在spring4.1后出的,它将数据封装,并可以设置sjonp返回函数。 MappingJacksonValue mappingJacksonValue=new MappingJacksonValue(message); mappingJacksonValue.setJsonpFunction(callback); return mappingJacksonValue; }
当然也可以自己拼相应的数据格式返回
@RequestMapping(value="/itemcat/message",produces=MediaType.APPLICATION_JSON_VALUE+";charset=utf-8") @ResponseBody public String getItemCatList(String callback){ String message="{'name':'盖伦','age':'30'}"; //把对象转化成json String json=JsonUtils.objectToJson(message); //拼装返回值 String result=callback+"("+json+");"; return result;
produces=MediaType.APPLICATION_JSON_VALUE+";charset=utf-8"
是设置返回数据的编码格式,防止乱码。
返回结果都是:getMessage("{'name':'盖伦','age':'30'}"); 即数据当做js函数的参数返回。
在jquery中succes就会js回调函数,得到success的参数就是得到了跨域返回的数据。
当然我只测试了一部分情况,还有许多情况没完善,有不周之处还请大家指正。