在前后端分离的项目中,跨越问题是大家都会遇到的,今天我们来聊聊项目中解决跨域有哪些方法:
使用Spring boot官方的注解去解决跨域的问题,直接在控制层上面加上注解,那么当前控制层下的请求方法就都处理了跨越的请求,不过在Spring boot 2.0以上版本之后,allowCredentials 默认是false,所以我们加注解的时候也需要改成true这样才能解决跨越问题:
@CrossOrigin(origins = "”,allowCredentials = “true”)
不过这种方式,不太友好,如果项目大的话,那么是不是所有的控制层都需要加上这个注解呢。
创建一个CorsFilter bean做为配置类,放开浏览器对ip的校验限制
@Configuration
@Order
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = buildConfig();
corsConfiguration.addExposedHeader("Authorization");
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
}
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowCredentials(true);
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");// 允许提交请求的方法,*表示全部允许
corsConfiguration.setMaxAge(18000L);
return corsConfiguration;
}
}
corsConfiguration.addExposedHeader(“Authorization”); 这行代码是前端传过来的一个类似 Token的凭证,是用于校验当前登陆的用户的Token是否过期没有,如果过期那么就让用户重新进行登录,所以大家需要改成自己的。
@Component
public class CrossDomainFilter implements Filter {
/**
* Default constructor.
*/
public CrossDomainFilter() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
@Override
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = ((HttpServletResponse) servletResponse);
System.out.println("CORSFilter HTTP Request: " + request.getMethod());
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "HEAD,POST, GET, OPTIONS,PUT, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
// response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
response.setHeader("Access-Control-Allow-Credentials", "true");
HttpServletResponse resp = (HttpServletResponse) servletResponse;
if (request.getMethod().equals("OPTIONS")) {
resp.setStatus(HttpServletResponse.SC_ACCEPTED);
return;
}
chain.doFilter(request, servletResponse);
}
/**
* @see Filter#init(FilterConfig)
*/
@Override
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
注意这个类 @Component 是要进行ioc 注册的,所以大家要对这个类进行扫描注册,才能使用,其次就是Token的问题了,
response.setHeader(“Access-Control-Allow-Headers”, “Origin, X-Requested-With, Content-Type, Accept, Authorization”);
这里的Authorization 就是,大家改成自己的名称叫可以使用了,
这三种方式,推荐大家使用 第3种,这种是作者在生产坏境测试通过的,上面2种,在通过header传递Token的时候,有时候就会出现跨越问题不能解决的情况,有时候就能解决很奇怪,不过大家可以的话就使用 nginx去做跨域问题吧。