一.前言
跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制。
同源策略:请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同
不同域名之间相互访问对于前后端分离的项目来说,如果前端项目与后端项目部署在两个不同的域下,那么会引起跨域的问题。
二.现象
1.前端ajax请求后台接口
function getCk() {
$.ajax({
url: "http://localhost:8002"+"/getCk",
type: 'GET',
success: function (data) {
layer.msg("结果:"+data);
}
});
}
2.后台接口
@GetMapping("/getCk")
@ResponseBody
public String getCk(){
return "hello world";
}
3.请求结果
Failed to load http://localhost:8002/getCk: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:63342’ is therefore not allowed access.
三.解决方案
1.使用JSONP
1.前端代码
$.ajax({
url: "http://localhost:8002"+"/getCk2",
type: 'GET',
dataType: 'jsonp',
success: function (date) {
layer.msg("结果:"+date);
}
});
2.后端代码
@GetMapping("/getCk2")
@ResponseBody
public String getCk2(String callback){
String result=callback+"("+ JSON.toJSONString("hello world2")+")";
return result;
}
3.结果
请求后的地址为:
http://localhost:8002/getCk2?callback=jQuery21404377760922496734_1546047342242&_=1546047342243
jsonp指定服务器返回的数据类型为jsonp格式,可以看发起的请求路径,自动带了一个callback=xxx,xxx是jquery随机生成的一个回调函数名称。
其原理跟 < scri pt> 脚本请求一样,因此使用jsonp时也只能使用GET方式发起跨域请求。跨域请求需要服务端配合,设置callback,才能完成跨域请求。所以不推荐使用
结果: hello word2
2.通过cors协议
(1) 使用crossOrigin注解
@CrossOrigin
@GetMapping("/getCk1")
@ResponseBody
public String getCk1(){
return "hello world1";
}
(2) 或者使用Filter拦截处理
@Component
public class Filter implements Filter {
/*跨域请求配置*/
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest reqs = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin","*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "5000");
response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,Authorization,Token");
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig filterConfig) {}
@Override
public void destroy() {}
}
(3) 继承webmvcconfigureradapter的方法
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET", "POST", "OPTIONS", "PUT")
.allowedHeaders("Content-Type", "X-Requested-With", "accept", "Origin", "Access-Control-Request-Method",
"Access-Control-Request-Headers")
.exposedHeaders("Access-Control-Allow-Origin", "Access-Control-Allow-Credentials")
.allowCredentials(true).maxAge(3600);
}
}