Java Spring Boot Webflux cors 被阻止
Posted
技术标签:
【中文标题】Java Spring Boot Webflux cors 被阻止【英文标题】:Java Spring Boot Webflux cors blocked 【发布时间】:2021-08-17 01:19:49 【问题描述】:我正在尝试使用 Webflux 构建一个 Angular 和 Spring Boot 应用程序,而不是一开始就被包含实体和数据库的完整 CRUD 教程所困扰,我想我会先看看我是否可以得到客户端显示服务器返回的字符串,正如 Spring Boot 的文档所教导的那样 here。为此,我有以下代码:
//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 新手,一直在四处寻找建议,但我通常会找到涉及配置、控制器类和其他比我目前拥有的更多构建工件的解决方案。我怎样才能让它工作?感谢您的帮助。
【问题讨论】:
Cors 是堆栈溢出中最常见的问题。 Spring 文档准确地告诉你如何解决这个问题,包括 100 多个在线教程和每周 50 个关于堆栈溢出的问题。 这是 java spring-boot 标签下被问得最多的问题。我已经阅读了您的问题,我对您的回答是 meta.***.com/questions/261592/… 注意 2 次投票。 CORS 上有大量文档developer.mozilla.org/en-US/docs/Web/HTTP/CORSdocs.spring.io/spring-framework/docs/current/reference/html/…spring.io/guides/gs/rest-service-corsspring.io/blog/2015/06/08/cors-support-in-spring-frameworkdocs.spring.io/spring-boot/docs/current/reference/htmlsingle/…en.wikipedia.org/wiki/Cross-origin_resource_sharingfetch.spec.whatwg.org/#http-cors-protocol 以后,使用 google 并找到您正在使用的框架的官方文档,并在询问堆栈溢出之前开始研究。这是您的答案docs.spring.io/spring-framework/docs/current/reference/html/…,它非常方便地位于官方 webflux 文档的 CORS 章节中。 【参考方案1】:确实,我确实需要使用CorsWebFilter
。然而,在阅读了一些关于 Spring Boot 及其依赖注入系统的内容,并查看了不使用功能端点的 Spring Boot 项目中不同的切线相关的 cors 实现后,我发现我必须将“CorsWebFilter”放在我的应用程序的根是这样的:
@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);
当然,这不是唯一的方法。但它解决了我最初遇到的这个小问题。谢谢大家。
【讨论】:
【参考方案2】:您已决定使用functional endpoints,并且您没有使用我从您的标签中可以看出的弹簧安全性,这意味着此处提供的所有其他答案都是错误的。
使用功能端点时,您必须知道您已选择不使用传统的基于注释的类。这意味着您失去了 spring 框架提供的许多免费功能
功能性端点更“低级”。因此,处理 CORS 的责任落在您开发人员身上。
如果你是 Spring 和 webflux 的初学者,我不会选择这条路线。
The documentation states in the CORS chapter in the official webflux documentation:
您可以通过内置的 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
【讨论】:
很好,谢谢。事实是我想“进入 Spring Boot”,但是当我开始查找时,困难在于如何制作这样的应用程序有太多选择让我决定使用什么 - gradle v maven,wars v jars,我应该使用哪些依赖项,等等。 所以,我认为只需将tutorial 连接到我的客户端就足够简单了。并不是我没有尝试搜索如何启用 cors,您在我的问题中看到我向 WebClient 添加了注释。显然,我的错误是我没有考虑功能端点,它们的工作方式与我使用弹簧安全性不同。 该 bean 是否应该被注入到另一个类中?通读你得到 bean 的那篇 baeldung 文章,点击相关文章,搜索功能端点,但它没有回答这个问题。我用 bean 创建了一个低于应用程序根级别的文件,将允许的来源更改为http://localhost:4200
,但仍然出现错误。尝试将允许的方法标头更改为Access-Control-Allow-Origin
,并将允许的方法更改为GET
,但仍然没有成功。
堆栈溢出不是论坛。这是一个问答网站。这个问题已经回答了。
Is the bean supposed to be injected into another class? Read through that baeldung article you got the bean from
我从不从 baeldung 网站获取信息,因为它们通常会提供错误的过时信息。如果您真的阅读了我的答案,您会发现我喜欢官方 webflux 文档,其中包含代码示例。如果你不明白答案,那么你应该从基础开始,也许从实现一个标准的 spring boot 应用程序开始,或者 google 上 bean 以及应该在哪里声明它们等等。【参考方案3】:
在需要快速测试的基于浏览器的前端使用 Webflux 时,我使用支持 CORS 的 Chrome 扩展来快速测试。这显然不适合生产。
如果您处于纯微服务/后端通信的情况,您可能只需要使用 Spring 的预期工作流程。以我的经验,Spring Webflux 有一些强大的结果,但设置很繁琐。您提到但正在避免的那些配置类,或者注解或基于 DSL 的 Kotlin 解决方案,不幸的是,目前是预期的方式。根据我的经验,它们确实有效,一旦你设置好它们,就可以为其他微服务制作一个快速的 github 就绪模板(我当时正在使用 Spring 和 Kotlin 构建微服务)。
编辑:我还要补充一点,你要避免的那些配置和类是值得你花时间的,即使你花一个上午的时间在这些上面也会为提高生产力铺平道路。 Webflux 很棒(我在 Kotlin 和 Java 中都使用过),但是当你跳转到异步/反应式 webflux 领域时,会有一些不可避免的陷阱和配置差异。当您意识到自己做对了事情时,配置中的乐趣就来了,当您可以推送这么多请求时,您的 DB 驱动程序会吓坏 :) :) :)
【讨论】:
感谢您的建议。探索这个的第一步很尴尬,这是在“好吧,我想要一个框架”和“好吧,让我们从小事做起”之间的考虑。【参考方案4】:您是否正确配置了 cors? 如果没有尝试以下: https://***.com/a/67605427/9295125
由于发布的答案缺少一行,请同时阅读第二个答案。
【讨论】:
谢谢。试图遵循这一点,但由于我没有将安全性作为依赖项包括在内,因此存在问题。使用 gradle,将compile "org.springframework.boot:spring-boot-starter-security"
添加到我的构建文件中,更新了类路径,但看起来它只是没有找到它。我可能会废弃并重新制作以安全性为依赖的项目,反正还没有做太多
用户没有指定使用spring security,从手头的问题来看,所以这不是一个答案,它链接到一个错误的答案。
对不起。原题中不包含使用的依赖或Pom以上是关于Java Spring Boot Webflux cors 被阻止的主要内容,如果未能解决你的问题,请参考以下文章
finishConnect(..) 失败:连接被拒绝:localhost/127.0.0.1,错误:Webflux、Webclient、Spring boot、java
Spring Boot WebFlux 2.1.7 中文翻译文档
使用 Spring Boot WebFlux、Spring Data MongoDB Reactive 和 ReactiveMongoRepository 更新 1 个或多个特定字段 MongoDB
spring-boot-starter-web 和 spring-boot-starter-webflux 不能一起工作吗?