因为安全性问题,浏览器遵守"同源策略"。(协议 、 域名 、 端口)必须完全一致.
但是有时候在应用会面临跨域问题。
- jsonp 方式
因为项目中基本都使用jquery,因此直接说明jquery方式(本质就是拼接创建script,script的src在加载资源时,进行了服务调用—解决跨域)
缺点: 只能进行GET请求(哪怕你在$.ajax 中type设置为 POST,发出的请求还是GET的)
$.ajax({
url:'其他不同源的访问',
// ...
dataType:'jsonp',
success:function(rt){
console.log(rt);
},error:function(rt)r
console.log(rt);
}
});
需要注意的是, 在服务端返回值时:
@Controller
public class TestController{
@GetMapping("/")
@ResponseBody
public String test(HttpServletRequest request){
String callback = request.getParameter("callback");
// 业务处理...
String json = // 业务处理要返回的数据
return callback + "(" + json + ")"
}
}
如果直接返回json串,会报错. 在jquery中,我们自己可以定义jsonpCallback: 函数名。从而在控制器中获取的callback就是我们自己的函数名。
也可以不指定jsonpCallback,如果不指定,jquery会随机生成一个函数名,最终处理在success函数中(就和我们不跨越的ajax调用一致。)
2) cros 方式
jsonp方式是可以处理一定程度上的跨域问题,但是限制在于必须是GET调用。CROS方式支持了所有的HTTP 动词请求方式,使用CROS方式,js端编码和原来的
(不跨域)方式没有任何区别(甚至没有感知),如果需要携带cookie,则需要添加一个额外参数.要使用CROS,最低需要使用IE10.
@Controller
public class CROSController{
// 支持跨域(allowCredentials="true"),则支持客户端跨域携带cookie等信息
@CrossOrigin()
@GetMapping("/")
public String(){
return "test data";
}
}
// 客户端携带 withCredentials=true
$.ajax({
url:'其他不同源的访问',
// ...
beforeSend: function (xhr) {
xhr.withCredentials = true
},
dataType:'json/text', // 不写也可以
success:function(rt){
console.log(rt);
},error:function(rt)r
console.log(rt);
}
});