目录
前言
虽然我这是针对自己的小项目解决的ajax跨域问题,但是我觉得这几种方式是通用的。
1.首页展示用户名
当用户登录成功后,用将token写入cookie中,使用js从cookie中取出token。根据token查询用户信息,将用户名展示在首页。
根据token查询用户信息有两种方案:
- 方案一
由于淘淘商城首页footer.jsp,在每个系统中都有,可以在每一个系统的footer.jsp中写一个ajax发起请求调用当前系统controller。
然后在每一个系统都写一个controller,从cookie中获取token,调用taotao-sso-service中的根据token获取用户信息。
- 方案二
当页面加载完成后使用js取cookie中token的数据,使用ajax请求taotao-sso-web的controller,查询用户信息JSON数据。只需要在页面实现一次即可。
乍一看方案一与方案二是一样的,其实不是,方案一需要在每一个系统都编写controller,方案二只需要在taotao-sso-web编写一个controller即可。而且方案一是立即可行的,但是方案二服务接口在sso系统(localhost:8088)中,在首页显示用户名称,首页的域名是localhost:8082,使用ajax请求跨域了。
2.如何解决ajax跨域
ajax无法跨域请求别的url,我们可以使用ajax跨域加载js
更加详细的解释:
3.jsonp实现
3.1前端jsonp两种实现方法
当页面加载footer.jsp时,会加载taotao.js,在taotao.js中会加载$({}),加载用户名
3.1.1方法一:自己写callback函数
使用ajax的dataType : "script",自己写callback函数。
首先$.cookie("COOKIE_TOKEN_KEY");从cookie中获取token,然后发起ajax请求,在url中我们要加上回调的函数,
dataType : "script",type : "GET" 是固定的,下面的fun()函数就是我们自己获取username,并设置到footer.jsp中
后端返回这样的fun(jsondata)调用,前端的fun(data)函数。
fun({"status":200,"msg":"OK","data":{"id":41,"username":"3","password":null,"phone":"3","email":null,"created":1535534637000,"updated":1535534637000}});
var TT = TAOTAO = {
checkLogin : function(){
var _ticket = $.cookie("COOKIE_TOKEN_KEY");//从cookie中获取token
if(!_ticket){
return ;
}
$.ajax({
//http://localhost:8088/user/token/12341654?callback=fun
url : "http://localhost:8088/user/token/" + _ticket+"?callback=fun",
dataType : "script",
type : "GET",
success : function(){
}
});
}
}
function fun(data) {
if(data.status == 200){
var username = data.data.username;
var html = username + ",欢迎来到淘淘!<a href=\"http://localhost:8088/user/logout/"
+$.cookie("COOKIE_TOKEN_KEY")+"\" class=\"link-logout\">[退出]</a>";
$("#loginbar").html(html);
}
}
$(function(){
// 查看是否已经登录,如果已经登录查询登录信息
TT.checkLogin();
});
3.1.2方法二:使用ajax自带的callback函数
使用ajax的dataType : "jsonp",将success:function当做回调函数
将dataType : "jsonp",ajax会自动调用success函数
这是使用ajax自带的callback函数:jQuery3895288
jQuery3895288({"status":200,"msg":"OK","data":{"id":41,"username":"3","password":null,"phone":"3","email":null,"created":1535534637000,"updated":1535534637000}});
taotao.js
var TT = TAOTAO = {
checkLogin : function(){
var _ticket = $.cookie("COOKIE_TOKEN_KEY");//从cookie中获取token
if(!_ticket){
return ;
}
$.ajax({
url : "http://localhost:8088/user/token/" + _ticket,
dataType : "jsonp",//ajax发起请求时会自动带上?callback=fun
type : "GET",
success : function(data){//相当于fun
if(data.status == 200){
var username = data.data.username;
var html = username + ",欢迎来到淘淘!<a href=\"http://localhost:8088/user/logout/"+_ticket+"\" class=\"link-logout\">[退出]</a>";
$("#loginbar").html(html);
}
}
});
}
}
$(function(){
// 查看是否已经登录,如果已经登录查询登录信息
TT.checkLogin();
});
3.2后端springmvc支持jsonp的两种实现方法
ajax设置的callback函数,我们在后端就需要封装一个callback(Jsondata),让前端将Jsondata作为参数调用。
3.2.1方法一:springmvc4.1之前的实现方法
/**
* 接收token,调用service服务获取用户信息
* @param token
* @return
*/
@RequestMapping(value="/user/token/{token}",method=RequestMethod.GET,
produces=MediaType.APPLICATION_JSON_VALUE+";charset=utf-8")
@ResponseBody
public String getUserByToken(@PathVariable String token,String callback) {
TaotaoResult result = loginService.getUserByToken(token);
String resultJson = JsonUtils.objectToJson(result);
//判断是否是jsonp
if(StringUtils.isNotBlank(callback)) {
//如果是jsonp,拼接fun({id:1})
System.out.println(callback + "(" + resultJson + ");");
return callback + "(" + resultJson + ");";
}
return resultJson;
}
在前端使用自定fun回调函数时,我们可以打印callback(Jsondata),将这个fun返回时,ajax就会掉这个callback(Jsondata)。
fun({"status":200,"msg":"OK","data":{"id":41,"username":"3","password":null,"phone":"3","email":null,"created":1535534637000,"updated":1535534637000}});
3.2.2方法二:springmvc4.1之后的实现方法
springmvc4.1以后,下面两行代码会自动帮我们封装callback(Jsondata)
MappingJacksonValue value = new MappingJacksonValue(Object);
value.setJsonpFunction(callback);
/**
* 接收token,调用service服务获取用户信息
* @param token
* @return
*/
@RequestMapping(value="/user/token/{token}",method=RequestMethod.GET,
produces=MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public Object getUserByToken(@PathVariable String token,String callback){
TaotaoResult result = loginService.getUserByToken(token);
//判断是否是jsonp
if(StringUtils.isNotBlank(callback)){
MappingJacksonValue value = new MappingJacksonValue(result);
value.setJsonpFunction(callback);
return value;
}
return result;
}