js跨域請求之jsonp原理和運用
1、js請求後端服務時,域名不同或域名相同埠不同都是跨域;
2、無論哪個瀏覽器js都不能跨域請求後端服務,解決辦法為jsonp;jsonp不是新技術,只是一個解決方案;即js不請求後端服務而是跨域請求js,即跨域載入js檔案,而這個js檔案由伺服器端返回。
3、js中可以在cookie中取出token
4、js跨域取資料時,即使資料返回來,但瀏覽器判斷是跨域取的資料也不會讓js拿到,自動遮蔽掉
5、jsonp原理圖:
上圖解釋:
情況1--直接請求:當localhost:8082 伺服器js檔案Ajax跨域請求時,localhost:8088處理資料正常返回json資料,返回到瀏覽器時被遮蔽掉,即localhost:8082上不能顯示請求的資訊
情況2--直接請求帶引數callback==mycall:當localhost:8082 伺服器js檔案Ajax跨域請求時,在js中Ajax請求程式碼中配置上daType:jsonp【jQuery已對jsonp進行了封裝,請求時在自己編寫的ajax請求連結後面自動攜帶引數callback=mycall 。此請求相當於src請求,請求一個遠端的js檔案,這個遠端的檔案中包含了伺服器端返回的資料,格式為mycall(data)。jQuery在本地js檔案中建立函式mycall(data),mycall函式名的值也為jQuery自動生成】,伺服器得到請求後,將json資料當引數封裝進mycall方法中以字串方式返回(相當於一個js檔案),瀏覽器識別為js檔案即不會去遮蔽,進而載入進js中,js呼叫mycall方法傳入引數,經過解析即可顯示資料。
js如圖配置即可:
程式碼:
var TT = TAOTAO = { checkLogin : function(){ var _ticket = $.cookie("TT_TOKEN"); if(!_ticket){ return ; } $.ajax({ url : "http://localhost:8088/user/token/" + _ticket, dataType : "jsonp", type : "GET", success : function(data){ if(data.status == 200){ var username = data.data.username; var html = username + ",歡迎來到淘淘!<a href=\"http://www.taotao.com/user/logout.html\" class=\"link-logout\">[退出]</a>"; $("#loginbar").html(html); } } }); } } $(function(){ // 檢視是否已經登入,如果已經登入查詢登入資訊 TT.checkLogin(); });
伺服器端處理:
程式碼:
@RequestMapping(value = "/token/{token}",method = RequestMethod.GET,
// 瀏覽器對返回的字串進行編碼成json,如果不設定可能會編譯失敗
produces =MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String getUser(@PathVariable("token")String token, String callback){
TaotaoResult result = userService.token(token);
if(StringUtils.isNotBlank(callback)){
return callback+"("+JsonUtils.objectToJson(result) +")";
}
return JsonUtils.objectToJson(result);
}
注意:在註解@RequestMapping中加上produces =MediaType.APPLICATION_JSON_UTF8_VALUE這句話,意思是瀏覽器對返回的字串進行編碼成json,如果不設定可能會編譯失敗,導致頁面上顯示不出資料
或者:
//jsonp方法2,僅限spring4.1版本以上
@RequestMapping(value = "/token/{token}",method = RequestMethod.GET)
@ResponseBody
public Object getUser(@PathVariable("token")String token, String callback){
TaotaoResult result = userService.token(token);
if(StringUtils.isNotBlank(callback)){
MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(result);
//設定回撥方法
mappingJacksonValue.setJsonpFunction(callback);
return mappingJacksonValue;
}
return result;
}
後臺js程式碼實現: