Spring Boot全局CORS配置已加载但未生效,Access-Control-Allow-Origin缺失
Spring Boot全局CORS配置未生效,局部@CrossOrigin正常工作的原因?
场景说明
前端站点部署在http://localhost:4200,调用部署在http://localhost:9090的Spring Boot REST服务。
REST控制器代码
@RestController @RequestMapping(value="/cog", name="cog") @OpenAPIDefinition(info = @Info(title = "Maillage territorial par le Code Officiel Géographique")) public class COGController { @RequestMapping(value = "/communesTriLocale", method=RequestMethod.GET) public List<Commune> obtenirCommunesTriParLocale( @RequestParam(name="anneeCOG") int anneeCOG, @RequestParam(name="locale") String locale) { [...] } }
全局CORS配置类
通过@Configuration类配置全局CORS:
@Configuration @EnableWebMvc public class CorsConfig implements WebMvcConfigurer { /** Logger. */ private static final Logger LOGGER = LoggerFactory.getLogger(CorsConfig.class); /** Mapping pour CORS. */ @Value("${backend.cors.mapping}") private String corsMapping; /** Origine autorisée pour CORS. */ @Value("${backend.cors.allowedOrigins:null}") private String corsAllowedOrigins; /** Méthodes HTTP autorisées pour CORS. */ @Value("${backend.cors.allowedMethods:null}") private String corsAllowedMethods; /** Exposed headers pour CORS. */ @Value("${backend.cors.exposedHeaders:null}") private String corsExposedHeaders; /** * {@inheritDoc} */ @Override public void addCorsMappings(CorsRegistry registry) { CorsRegistration registration = registry.addMapping(this.corsMapping); LOGGER.info("Les règles CORS du backend métier autorisent pour pour le mapping {} :", this.corsMapping); if (this.corsAllowedOrigins != null) { registration.allowedOrigins(this.corsAllowedOrigins); LOGGER.info("\t- AllowedOrigins : {}", this.corsAllowedOrigins); } if (this.corsAllowedMethods != null) { registration.allowedMethods(this.corsAllowedMethods); LOGGER.info("\t- AllowedMethods : {}", this.corsAllowedMethods); } if (this.corsExposedHeaders != null) { registration.exposedHeaders(this.corsExposedHeaders); LOGGER.info("\t- ExposedHeaders : {}", this.corsExposedHeaders); } } }
启动日志确认CORS规则加载成功
Spring Boot启动日志显示CORS规则已正确加载:
INFO Application : Starting Application v0.0.12-SNAPSHOT using Java 17.0.6 on debian with PID 449341 [...] INFO TomcatWebServer: Tomcat initialized with port(s): 9090 (http) [...] INFO CorsConfig : Les règles CORS du backend métier autorisent pour pour le mapping /** : INFO CorsConfig : - AllowedOrigins : http://localhost:4200 INFO CorsConfig : - AllowedMethods : GET,POST,PUT,PATCH,DELETE,OPTIONS INFO CorsConfig : - ExposedHeaders : Authorization
前端调用返回403错误
使用Angular通过OpenApi生成的代码调用接口http://localhost:9090/cog/communesTriLocale?anneeCOG=2022&locale=fr_FR时,返回403错误,提示:
跨源请求被阻止:同源策略不允许读取位于 http://localhost:9090/cog/communesTriLocale?anneeCOG=2022&locale=fr_FR 的远程资源。原因:CORS头“Access-Control-Allow-Origin”缺失。状态码:403。
请求头
GET /cog/communesTriLocale?anneeCOG=2022&locale=fr_FR HTTP/1.1 Host: localhost:9090 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0 Accept: */* Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate, br Origin: http://localhost:4200 Connection: keep-alive Referer: http://localhost:4200/ Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-site
响应头
HTTP/1.1 403 Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers Transfer-Encoding: chunked Date: Mon, 12 Jun 2023 06:00:33 GMT Keep-Alive: timeout=60 Connection: keep-alive
curl调用接口正常
使用curl命令调用该接口返回200状态码,响应正常:
请求
* Connected to localhost (::1) port 9090 (#0) > GET /cog/communesTriLocale?anneeCOG=2022&locale=fr_FR HTTP/1.1 > Host: localhost:9090 > User-Agent: curl/7.74.0 > Accept: */*
响应
< HTTP/1.1 200 < Vary: Origin < Vary: Access-Control-Request-Method < Vary: Access-Control-Request-Headers < Content-Type: application/json < Transfer-Encoding: chunked < Date: Mon, 12 Jun 2023 06:13:38 GMT
局部@CrossOrigin注解生效
排查代码未发现其他冲突的CORS配置,但在REST控制器上添加@CrossOrigin注解后,接口可正常工作:
@CrossOrigin(origins = {"http://localhost:8080", "http://localhost:4200", "http://localhost:9090", "http://localhost:9091"})
请问为何全局CORS配置未生效,导致响应中缺少Access-Control-Allow-Origin头?
内容的提问来源于stack exchange,提问作者Marc Le Bihan
相关产品推荐
相关产品推荐

