跨域产生的原因
在一个项目中,使用js的ajax请求,请求另外一个系统的数据时(协议不同(http、https)、域名不同、域名相同但端口号不同),能够请求到数据,但是因为这是跨域请求,浏览器不允许js拿到数据,这就是ajax跨域请求
解决方案
可以jsonp解决js的跨域请求,Jsonp不是新技术,是跨域的解决方案。因为在系统中可以通过跨域来加载js文件,所以可以使用js的特性绕过跨域请求。
jsonp的原理
一个系统的访问url是localhost:8082,它需要同ajax请求来访问localhost:8088下的json数据,此时因为两个系统的端口不同,所以产生了ajax跨域请求,浏览器不允许js取得数据,此时,可以使用jsonp来结局跨域请求,定义一个js方法mycall(data){},data就是返回的从另一个服务返回的json数据,可以在这个方法中拿到json数据进行业务处理,而在ajax请求中,只需要多携带一个参数callback=mycall,在服务器接收到这个ajax请求之后,判断参数中是否有callback,如果有,就将json数据封装成一个js语句,返回到浏览器,返回的是"mycall({id:xx,name:xx});" 里面的数据就是json字符串,但js接收到这个响应后,就会调用mycall方法,就实现可跨域请求数据
jsonp的实现
- 客户端:
可以直接使用jquery封装jsonp,只需要在ajax请求中加上dataType : “jsonp”, 其余的按照普通ajax处理方式,jquery内部写了一个方法callback(data),而且会自动在这个请求后面加上参数callback=mycall,参数名就是callback,但返回响应后,会自动调用mycall方法,将数据注入ajax请求的success : function(data){}中的data - 服务端:
@Controller
public class TokenController {
@Autowired
private TokenService tokenService;
/**
* 根据token,从redis中取出用户信息
* 如果是ajax跨域请求,则需要jsonp请求,需要传递一个callback参数,并且需要返回一个String类型的js语句
* 如果返回String的话,返回的的response默认是Content-Type默认是text/html,
* 这里需要用produces = MediaType.APPLICATION_JSON_UTF8_VALUE指明返回json类型的数据
* @param token
* @param callback
* @return
*/
/*@RequestMapping(value = "/user/token/{token}",
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String getUserByTokenFromRedis(@PathVariable String token, String callback){
Result result = tokenService.getUserByTokenFromRedis(token);
//响应结果之前,判断是否为jsonp请求,是的话把结果封装成js语句返回
if(StringUtils.isNotBlank(callback)){
return callback + "(" + JsonUtils.objectToJson(result ) + ");";
}
return JsonUtils.objectToJson(result );
}*/
/**
* 这个方法的写法和上述的效果是一样的,上面的是spring4.1以前的原生的写法,这个是4.1以后的封装了之后的写法
* @param token
* @param callback
* @return
*/
@RequestMapping(value = "/user/token/{token}")
@ResponseBody
public Object getUserByTokenFromRedis(@PathVariable String token, String callback){
Result result = tokenService.getUserByTokenFromRedis(token);
//响应结果之前,判断是否为jsonp请求,是的话把结果封装成js语句返回
if(StringUtils.isNotBlank(callback)){
MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(result );
mappingJacksonValue.setJsonpFunction(callback);
return mappingJacksonValue;
}
return result ;
}
}