繁体   English   中英

Java Spring 引导 Webflux cors 被阻止

[英]Java Spring Boot Webflux cors blocked

我正在尝试使用 Webflux 构建一个 Angular 和 Spring 引导应用程序,而不是一开始就被包含实体和数据库的完整 CRUD 教程所困扰,我想我首先看看我是否可以让客户端显示服务器返回的字符串,正如 spring boot 的文档在这里所教的那样。 为此,我有以下代码:

//Angular client
  private currencyGreetingUrl: string;

  constructor(private http: HttpClient) {
    this.currencyGreetingUrl = 'http://localhost:8080/currency';
  }

  public getCurrencyGreeting(): Observable<string> {
    return this.http.get<string>(this.currencyGreetingUrl);
  }

//Spring Boot Web Client
@CrossOrigin(origins = "http://localhost:4200")
public class CurrencyWebClient {
  private WebClient client = WebClient.create("http://localhost:8080");

  private Mono<ClientResponse> result = client.get()
      .uri("/currency")
      .accept(MediaType.TEXT_PLAIN)
      .exchange();
  
  public String getResult() {
    return ">> result = " + result.flatMap(res -> res.bodyToMono(String.class)).block();
  }
}

//Spring boot handler
@Component
public class CurrencyHandler {

  public Mono<ServerResponse> currency(ServerRequest request) {
    return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN)
      .body(BodyInserters.fromValue("Hello, Currency On The Go!"));
  }
}

//Spring Boot router

@Configuration
public class CurrencyRouter {

  @Bean
  public RouterFunction<ServerResponse> route(CurrencyHandler currencyHandler) {

    return RouterFunctions
      .route(RequestPredicates.GET("/currency").and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), currencyHandler::currency);
  }
}

但是,我在运行客户端和服务器时收到此错误Access to XMLHttpRequest at 'http://localhost:8080/currency' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

我是 Spring Boot 的新手,并且一直在四处寻找建议,但我通常会找到涉及配置、controller 类和其他比我目前拥有的更多内置工件的解决方案。 我怎样才能让它工作? 我很感激任何帮助。

您已决定使用功能端点并且您没有使用 spring 我可以从您的标签中看出的安全性,这意味着此处提供的所有其他答案都是错误的。

使用功能端点时,您必须知道您已选择不使用传统的基于注释的类。 这意味着您失去了 spring 框架提供的许多免费功能

功能端点更“低级”。 因此,开发人员有责任处理 CORS。

如果您是 Spring 和 webflux 的初学者,我不会选择这条路线。

官方 webflux 文档的 CORS 章节中的文档说明

您可以通过内置的 CorsWebFilter 应用 CORS 支持,非常适合功能端点

他们甚至提供了一个标准 CORS 过滤器的实现,您可以根据自己的需要进行定制。

@Bean
CorsWebFilter corsFilter() {

    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);

    return new CorsWebFilter(source);
}

互联网上有 100 多个网页解释了 CORS,这是 spring-boot、spring-security 标签中最常见的问题。 我建议你阅读 CORS (在问这里之前你应该这样做)。

我强烈建议您从这里开始阅读:

Mozilla CORS

你有没有正确配置cors? 如果不尝试以下: https://stackoverflow.com/a/67605427/9295125

另请阅读第二个答案,因为发布的答案缺少一行。

在我需要快速测试的基于浏览器的前端使用 Webflux 时,出于我的目的,我使用支持 CORS 的 Chrome 扩展来快速测试。 这显然不适合生产。

如果您处于纯微服务/后端通信的情况,您可能只需要 go 与 Spring 的预期工作流。 根据我的经验,Spring Webflux 有一些强大的结果,但设置却很挑剔。 您提到但正在避免的那些配置类,或者 Kotlin 的注释或基于 DSL 的解决方案,不幸的是,目前是预期的方式。 根据我的经验,它们确实有效,一旦你设置好它们,就可以为其他微服务制作一个快速的 github 就绪模板(我当时正在使用 Spring 和 Kotlin 构建微服务)。

编辑:我还要补充一点,你要避免的那些配置和类是值得你花时间的,即使你花一个上午的时间在这些上面也会为大量的生产力铺平道路。 Webflux 很棒(我已经将它与 Kotlin 和 Java 一起使用)但是当您跳转到异步/反应式 webflux 领域时,会有一些不可避免的陷阱和配置差异。 当您意识到自己做对了事情时,配置中的乐趣就来了,当您可以推送如此多的请求时,您的 DB 驱动程序就吓坏了:):):)

事实上,我确实需要使用CorsWebFilter 然而,在阅读了一点 Spring Boot 及其依赖注入系统,并查看了 Spring Boot 项目中没有使用的``sCorFilter我的应用程序的根是这样的:

@SpringBootApplication
public class ServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServerApplication.class, args);
        CurrencyWebClient client = new CurrencyWebClient();

        System.out.println(client.getResult());
    }

    @Bean
    CorsWebFilter corsFilter() {

        CorsConfiguration config = new CorsConfiguration();

        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://localhost:4200");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");

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

        return new CorsWebFilter(source);
    }
}

当然,这不是唯一的方法。 但它解决了我最初遇到的这个小问题。 谢谢大家。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM