如何使用 webflux 在 Spring Boot 2 中处理 HTTP OPTIONS 请求?

How to handle HTTP OPTIONS requests in Spring Boot 2 with webflux?

我将 cors 配置如下:

@Bean
WebFluxConfigurer corsConfigurer() {
    return new WebFluxConfigurerComposite() {

        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**").allowedOrigins("*")
                    .allowedMethods("*");
        }
    };
}

我的POST就是这样的:

@Bean
RouterFunction<ServerResponse> routes() {
    return route(POST("/create")
                          .and(accept(APPLICATION_JSON))
                          .and(contentType(APPLICATION_JSON)), serverRequest 
                                 -> create(serverRequest);
}

无论如何,我的 angular 应用程序无法发出任何请求,直到我像这样添加 OPTIONS 路由:

@Bean
RouterFunction<ServerResponse> routes() {
    return route(POST("/create")
                          .and(accept(APPLICATION_JSON))
                          .and(contentType(APPLICATION_JSON)), serverRequest 
                                 -> create(serverRequest)
         .andRoute(OPTIONS("/create"), serverRequest -> ServerResponse.ok().build());
}

有必要吗?有什么方法可以删除此 OPTIONS 处理吗?

OPTIONS 请求是 Cross-origin 资源共享 (CORS) 中的 pre-flight 请求,它们是跨不同来源发出请求所必需的。

此 pre-flight 请求由某些浏览器发出,作为一种安全措施,以确保所完成的请求受到服务器的信任,服务器了解方法、来源和 headers 在请求中发送很安全。

流程是这样的:

  1. 客户端使用选项向服务器发送请求
  2. 如果 OPTIONS 请求成功,则客户端向服务器发送实际请求。

您可能还需要公开 headers。

@Bean
    WebFluxConfigurer corsConfigurer() {
        return new WebFluxConfigurerComposite() {

            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedOrigins("*")
                        .allowedMethods("*")
                .exposedHeaders("*");
            }
        };
    }

这取决于。

如果您的后端和前端构建在同一台服务器上并使用相同的端口, 不需要支持选项。

如果没有,您必须支持 OPTIONS,因为它用于识别您的服务器上允许哪些方法 prevent/allow CORS(跨源资源共享)。

所有最新的现代浏览器都通过发送 HTTP OPTIONS 来检查它来实现 CORS。 如果您的服务器拒绝或拒绝,浏览器将禁止您的请求。

我认为 WebFlux 功能端点不支持此功能。 Spring Framework reference documentation points to the CorsWebFilter instead.

您可以定义一个 CorsWebFilter @Bean 并使用自定义配置 CorsConfiguration 来实现相同的目的。

我在通过 "addCorsMappings" 添加 CORS 时遇到了同样的问题(就像你所做的那样) 上面的配置似乎不支持 OPTIONS 路由。仅此而已。

@Bean
CorsWebFilter corsFilter() {
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("http://domain1.com");
    config.addAllowedHeader("*");
    config.addAllowedMethod("*");

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", config);

    return new CorsWebFilter(source);
}