前提:
-
本文都是基于 spring boot 的解决方案。关于CORS的名词的解释等问题及流程,可参见后面的reference地址,不再赘述。
问题:
- 和前端对接,存在跨域问题,且放在header里面的Authorization值一直无法获取。
解决办法:
第一种方法:在config配置文件中添加下面代码类。这里有个问题,如果我们添加其他的filter拦截器,在处理顺序优先级上有前后之分;可能会出现我这样的情况——跨域问题解决了,但是就是无法获取到header中的放置的key为Authorization的value值(在这个前面的拦截器先去header里拿值,会一直为null,导致后面认证一直是401,但此时的跨域还是没问题的。这是我踩的坑)。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* @description: 处理请求跨域问题
* @author: jcc
* @date: 2018-11-16 11:51
* @Modified By:
*/
@Configuration
public class CORSConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedHeaders("*")
.allowedMethods("*")
.allowedOrigins("*");
}
};
}
}
第二种方法:在config配置文件中添加下面代码类。这里很重要的一点是,在有其他拦截器的时候,通过bean.setOrder(0);设置加载顺序,我是通过这个方式解决问题的(我其实是没把这个代码类放到config配置文件中,而是把下面代码中的Bean复制到主函数中了)。
@Configuration
public class CorsConfig {
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
// 设置你要允许的网站域名,如果全允许则设为 *
config.addAllowedOrigin("http://localhost:4200");
// 如果要限制 HEADER 或 METHOD 请自行更改
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
// 这个顺序很重要哦,为避免麻烦请设置在最前
bean.setOrder(0);
return bean;
}
}
第三种方法:在主函数配置这个Bean或者在config中添加此Bean的配置;但是这没发设置顺序。
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); // 允许cookies跨域
config.addAllowedOrigin("*");// 允许向该服务器提交请求的URI,*表示全部允许。。这里尽量限制来源域,比如http://xxxx:8080 ,以降低安全风险。。
config.addAllowedHeader("*");// 允许访问的头信息,*表示全部
config.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
config.addAllowedMethod("*");// 允许提交请求的方法,*表示全部允许,也可以单独设置GET、PUT等
/* config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");// 允许Get的请求方法
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");*/
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
Reference:
重拾后端之Spring Boot(五) -- 跨域、自定义查询及分页
Spring Cloud 前后端分离后引起的跨域访问解决方案
注:预留问题——网关和后面具体的微服务都设置解决跨域的配置,是否有问题。