项目需求要前后端分离,用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("*");
}
}
简单的实现了一下,具体复杂的用法和问题没有涉及,有机会再深入研究吧,这样前端代码正常写就行,实现了跨域访问。