SpringBoot裡的CORS 實現跨域訪問
專案需求要前後端分離,用RESTful介面的形式呼叫服務,這個時候就出現了跨域訪問的問題,
想了兩種方案,
一種是ajax 的jsonp的形式來解決但是有侷限性,以下是網上找的比較形象的介紹:
JSONP的基本原理即是:利用HTML的<script>標籤可獲取任何來源JavaScript程式碼的特點,實現資料的跨域訪問。在本地定義一個callback,通過<script>標籤的src屬性獲取遠端API的資料(將callback函式名傳遞過去),遠端伺服器的API需要符合JSONP的規範,即將原本JSON格式的輸出資料改寫為javascript的函式呼叫程式碼(callback為函式,原JSON資料為引數);這樣API返回的不再是JSON格式的資料而是JavaScript的程式碼。(預設只支援get請求方式)
JSON是一種資料交換格式,而JSONP是一種依靠開發人員的聰明才智創造出的一種非官方跨域資料互動協議。我們拿最近比較火的諜戰片來打個比方,JSON是地下黨們用來書寫和交換情報的“暗號”,而JSONP則是把用暗號書寫的情報傳遞給自己同志時使用的接頭方式。一個是描述資訊的格式,一個是資訊傳遞雙方約定的方法。
為了便於客戶端使用資料,逐漸形成了一種非正式傳輸協議,人們把它稱作JSONP,該協議的一個要點就是允許使用者傳遞一個callback引數給服務端,然後服務端返回資料時會將這個callback引數作為函式名來包裹住JSON資料,這樣客戶端就可以隨意定製自己的函式來自動處理返回資料了。
注意:訪問的伺服器返回的資料需要符合jsonp支援的json格式
例子如下:
注意後臺返回的json串要用設定的jsonpCallback的名字包起來,否則無法獲取資料;
前端請求:
$.ajax({
url: url,
type: "GET",
crossDomain: true,
data:data,
dataType:"jsonp",
jsonpCallback : "getDataCallback",//
jsonp:'callback',
success:function(result){
alert(result);
},
error:function(){
alert("error");
}
});
後臺 return "getDataCallback+(" + jsonString + ")";
這種方式特別麻煩,並且侷限性很大,預設只支援get請求,跟bootstrap-table結合使用時還比較麻煩,需要重寫ajax,而且queryParams 重寫引數會不起作用,只能手動設定data
$("#table").bootstrapTable({
ajax : function (request) {
$.ajax({
type : "GET",
url : url,
contentType: "application/json;charset=utf-8",
dataType:"jsonp",
data:'',
jsonpCallback : "getDataCallback",//
jsonp:'callback',
success : function (msg) {
request.success({
row : msg
});
$('#table').bootstrapTable('load', msg);
},
error:function(){
alert("錯誤");
}
});
},
queryParams : function queryParams(params) {
var param = {
merchantId : merchantId,
clientName : clientName,
pageNo : params.pageNumber, //divide page current page
pageSize : params.pageSize
};
return param;
}, //send params(*)
pagination : false,
striped : true,
cache : false,
onLoadSuccess : function() {
},
onLoadError : function(data) {
}
});
非常麻煩最終捨棄,決定用CORS來實現
二是CORS來實現
CORS介紹可以看這個文章:http://www.ruanyifeng.com/blog/2016/04/cors.html
因為我的後臺服務是用的springboot框架, 版本:<version>1.5.14.RELEASE</version>,搞了jsonp半天才發現框架已經支援了,尷尬兩行程式碼搞定。
@Configuration
public class ConnectionManageConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedHeaders("*")
.allowedMethods("*")
.allowedOrigins("*");
}
}
簡單的實現了一下,具體複雜的用法和問題沒有涉及,有機會再深入研究吧,這樣前端程式碼正常寫就行,實現了跨域訪問。