我尝试按照此 Spring 站点的建议为部署到 Pivotal Cloud Foundry 的 Spring Boot 应用程序实现 GLOBAL CORS。
https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/cors.html
但是,当我向服务端点发送 OPTIONS 消息时,响应中不会返回任何 CORS 标头。因此,应用程序在预检后无法进行 POST 调用。这是我的实现。
@Configuration
@EnableWebMvc
public class CORSConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("*/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "OPTIONS")
.allowedHeaders("Content-Type", "Authorization")
.allowCredentials(false).maxAge(3600);
}
}
我错过了什么吗?
好的。我找到了问题所在。 HTTP OPTIONS 请求本身并不构成预检请求。为了使 OPTIONS 被视为飞行前请求,它还需要 2 个请求标头。一个是 Origin,我将其添加到请求中。然而,我错过的是访问控制请求方法。浏览器生成的飞行前请求将包含所有 3 个 http 请求标头。添加所有 3 个请求标头后,我看到我的 CORS 标头在响应中返回。
这是示例代码和响应。
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@EnableWebMvc
public class CORSConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("POST")
.allowedHeaders("Content-Type", "Authorization")
.allowCredentials(false)
.maxAge(32400); // 9 hours max age
}
}
这是请求:
OPTIONS /my-end-point HTTP/1.1
Host: my-app.my-domain.com
Origin: http://localhost:8090
Access-Control-Request-Method: POST
Cache-Control: no-cache
Postman-Token: bc7171bc-7f84-3b44-a304-818627411a72
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
这是回复。
access-control-allow-methods →POST
access-control-allow-origin →*
access-control-max-age →32400
从 Spring Boot 3.3 开始,您需要执行以下操作来为您的应用程序配置 CORS。
在SecurityFilterChain中添加CORS配置:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) {
http.cors(Customizer.withDefaults()); //or however else you would like to configure CORS
//other settings
return http.build();
}
创建一个名为 corsFilter 的 Bean:
@Bean
public CorsFilter corsFilter() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOriginPatterns(List.of("https://*.example.net"));
configuration.setAllowedHeaders(List.of("Origin", "Content-Type", "Accept", "responseType", "Authorization"));
configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "OPTIONS", "DELETE"));
configuration.setMaxAge(3600L);
configuration.setAllowCredentials(true);
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return new CorsFilter(source);
}
以上是配置示例。请根据您所需的设置进行配置。
相关标头将添加到有效 PreFlight (OPTIONS) 请求的响应中。