跨域小结
前言
最近在开发过程中通过 js 调用其他服务接口时出现跨域问题,ajax 请求其他系统接口,能调通但是却总是进 error 方法,很是奇怪,页面控制台有错误信息,经查询是跨域导致的,因为使用的是 IE 浏览器,之前将服务的 ip 设置了安全站点,仍然有错误信息。网上很多关于跨域的帖子,但是看完总感觉缺点什么,所以还是自己总结一下。
解决方案
首先我的项目是 SpringBoot + template 以及 JQuery 等,由于是内网环境所以通过设置 ip 调用。以下是两种解决方式:
- 后台接口支持跨域
前端 js 如下:
//js方法,传入业务系统调用接口地址,以及参数 id
common.callBack = function (url, id) {
if (url != null && url !== "") {
url = url.replace("${id}", id);
$.ajax({
type: 'get',
url: url,
cache: false,
success: function (data) {
console.log("成功" +data);
},
error: function (message) {
console.log("失败");
}
});
}
};
后端未修改时业务系统接口能调通且能获取到参数id,但是页面总报错,通过断电调试,总是进 error 方法,如下:
解决方法,通过后端接口修改响应头实现,测试代码如下:
@GetMapping("testHd")
public String testHd(String id, HttpServletResponse response) {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Allow-Methods", "Content-Type, X-Requested-With, accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,token");
log.error("回调地址id " + id );
JSONObject jsonObject = new JSONObject();
jsonObject.put("success",true);
return jsonObject.toJSONString();
}
因为使用的是 IE 浏览器,一般会将本服务的 ip 设置在安全站点里,这样跨域问题就解决了。
- 通过 jsonp 解决,当然业务系统的接口也需要配合改动
前端 js 如下:
//js方法,传入业务系统调用接口地址,以及参数 id
common.callBack = function (url, id) {
if (url != null && url !== "") {
url = url.replace("${id}", id);
$.ajax({
type: 'get',
url: url,
dataType: 'jsonp', //参数类型设置为 jsonp
jsonp: 'callback', //自定义 jsonp 的值
data: '', // 如果没有其他参数 data 设置为空
contentType: 'application/json:utf-8', //响应结果为 json
cache: false,
success: function (data) {
console.log("成功" +data);
},
error: function (message) {
console.log("失败");
}
});
}
};
若 js 设置有误可能会报错:SCRIPT1004: 缺少 ‘;’,或者业务系统接口没有接手参数 callback 也会报错。所以业务系统接口测试代码如下:
@GetMapping("testHd")
public String testHd(String id, String callback) {
log.error("回调地址id " + id +", callback:" + callback);
JSONObject jsonObject = new JSONObject();
jsonObject.put("success",true);
return callback+ "("+jsonObject+")";
}
通过 callback 将结果包裹返回。具体原理以及跨域的概念等网上很多可以自行查看,以上仅是本人问题解决方式,当然跨域还有其他方式可以解决。