目錄
前言
雖然我這是針對自己的小項目解決的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
更加詳細的解釋:
https://blog.csdn.net/pdsu161530247/article/details/82189866
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;
}