什么是跨域?
就是在A网站中访问B网站的资源,此时违反了浏览器同源策略,就会出现跨域的问题。
什么情况下会出现跨域问题?
不同域名下访问
这个不用说,自然会出现跨域问题
主域和子域之间访问
www.ty.com
abc.ty.com
此时2个域名之间相互访问会出现跨域问题
域名相同,端口不同
www.ty.com:10000
www.ty.com:12000
域名相同,协议不同
https://www.ty.com
http://www.ty.com
http和https之间也会出现跨域问题
解决跨域问题的方案有很多种,包括前端的jsonp跨域,nginx代理跨域等,当然后端也能解决跨域问题
下面是几种java解决跨域的方式
使用Filter
@WebFilter(filterName = "BusinessCorsFilter ")
@Configuration
public class BusinessCorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin","*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Max-Age", "3600");
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
使用Filter过滤器全局配置,较为方便。上面使用的是springboot的@WebFilter注解,如果是spring,需要在xml里配置filter-name和filter-path
使用WebMvcConfigurer
@Configuration
public class BusinessCorsConfigurer implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true).maxAge(3600);
}
}
这种也是全局配置,其实本质上和第一种使用filter方式没什么区别,都是同一种解决方案,执行方式不同而已。
使用@CrossOrigin
@CrossOrigin(origins = "http://127.0.0.1:8888", maxAge = 3600)
@RestController
public class TestCros {
@GetMapping("/getCurrentDate")
public Object getCurrentDate(){
return DateUtil.now();
}
}
@RestController
public class TestCros {
@CrossOrigin(origins = "http://127.0.0.1:8888", maxAge = 3600)
@GetMapping("/getCurrentDate")
public Object getCurrentDate(){
return DateUtil.now();
}
}
@CrossOrigin注解方式和上面两种全局配置不同,属于方法级或类级配置。简而言之,就是该注解可以加在方法上,也可以加在controller层上,即可获取与之对应的控制级别
origins : 允许可访问的域列表,不配置的话相当 * ,即全部
maxAge:准备响应前的缓存持续的最大时间,单位 秒。
第一种和第二种本质上属于同一种解决方式,在不同使用环境下,哪种方面使用哪种,且都是全局配置,方便、简洁、实用。
第三种注解方式的优点在于灵活,在某些应用场景下,不想将全局设置为跨域访问可以使用这种方式。