问题描述
最近在调试VUE前端网页时,访问一个Spring-Boot的后端服务器时没有获得期望的响应,浏览器控制台中提示“No 'Access-Control-Allow-Origin' header is present on the requested resource.”

image.png
解决办法
该问题是一个跨域资源共享(CORS)的问题,即由于浏览器的安全性限制,不允许AJAX访问协议不同、域名不同、端口号不同的数据接口,否则就会出现上述错误。
Spring下有多种方案可以解决此问题。
方法1:使用注解(简单,推荐)
在Controller类或相应的方法上添加@CrossOrigin注解。
在类上添加表示该类中的所有mapping方法均支持跨域访问,而添加到对应的方法上表示仅该方法支持跨域访问。
默认情况下,@CrossOrigin允许:
- 所有域(origin)
- 所有header
- 所有HTTP方法
可以通过@CrossOrigin注解中的属性来设置更严格的跨域访问。
- value/origins:允许访问的域的列表,例如“http://domain1.com”,表示来自 http://domain1.com 域的请求是支持跨域的。默认为“*”,表示所有域都被允许。
- allowedHeaders:允许的请求头。默认为“*”,表示该域中的所有的请求头都被允许。
- maxAge:表示预检(preflight)请求的有效期,在该有效期内,不用每次发送请求时都先发送预检请求,单位是秒。如果值设置为负值则表示使用默认值,默认值为1800秒,即30分钟。
- methods:支持的HTTP方法,例如“GET、POST”等,如果不设置,表示使用
RequestMapping中定义的方法。- allowCredentials:表示是否在请求中携带凭证(Credentials),凭证可以是cookie、authorization headers或其他(cookie的情况比较多)。
方法2:全局配置
全局配置需要添加自定义类实现WebMvcConfigurer接口或继承WebMvcConfigurerAdapter,然后实现addCorsMappings方法,在实现方法中对CROS进行设置,如下是一个配置示例:
@Override
public void addCorsMappings(CorsRegistry registry) {
// 解决vue访问时的跨域问题:No 'Access-Control-Allow-Origin' header is present on the
// requested resource.
registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET", "PUT", "POST").allowCredentials(true).maxAge(3600)
.allowedHeaders("*");
}
其中,addMapping表示对哪种格式的请求路径进行跨域支持。其他方法的含义可以参照方案一中关于@CrossOrigin的属性的说明。
通常由@Configuration标记的配置类实现或继承以上类。
方法3:CORS Filter
可以使用内置的CorsFilter来支持CORS。
一个示例代码如下:
CorsConfiguration config = new CorsConfiguration();
// Possibly...
// config.applyPermitDefaultValues()
config.setAllowCredentials(true);
config.addAllowedOrigin("https://domain1.com");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
CorsFilter filter = new CorsFilter(source);