Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java WebTestClient-带有Spring引导和Webflux的CORS_Java_Spring Boot_Cors_Spring Webflux_Same Origin Policy - Fatal编程技术网

Java WebTestClient-带有Spring引导和Webflux的CORS

Java WebTestClient-带有Spring引导和Webflux的CORS,java,spring-boot,cors,spring-webflux,same-origin-policy,Java,Spring Boot,Cors,Spring Webflux,Same Origin Policy,我有Vuejs前端和Spring Boot Webflux控制器。现在浏览器在调用Spring Boot时向CORS抱怨 访问位于的XMLHttpRequest'https://...“起源”https://...'已被CORS策略阻止:对飞行前请求的响应未通过访问控制检查:请求的资源上不存在'access control Allow Origin'标头。 为了启用CORS,我尝试使用@CrossOrigin注释,如下所述: 但是它没有帮助,而且Spring在响应中没有发送CORS头,即使控制器

我有Vuejs前端和Spring Boot Webflux控制器。现在浏览器在调用Spring Boot时向CORS抱怨

访问位于的XMLHttpRequest'https://...“起源”https://...'已被CORS策略阻止:对飞行前请求的响应未通过访问控制检查:请求的资源上不存在'access control Allow Origin'标头。

为了启用CORS,我尝试使用@CrossOrigin注释,如下所述:

但是它没有帮助,而且Spring在响应中没有发送CORS头,即使控制器中有@CrossOrigin注释

我还尝试了Bealdung教程中描述的WebTestClient,它确认了标题不存在:

java.lang.AssertionError: Response header 'Access-Control-Allow-Origin' expected:<[*]> but was:<null>

> OPTIONS /cors-enabled-endpoint
> WebTestClient-Request-Id: [1]
> Origin: [http://any-origin.com]
> Access-Control-Request-Method: [GET]

No content

< 500 INTERNAL_SERVER_ERROR Internal Server Error
< Vary: [Origin, Access-Control-Request-Method, Access-Control-Request-Headers]

0 bytes of content (unknown content-type).

你知道为什么上面链接中描述的CORS配置不起作用吗?我还尝试在全局配置上启用CORS,并使用WebFilter启用CORS。但似乎什么都不起作用。

@CrossOrigin

SpringWebMVC和SpringWebFlux都通过 RequestMappingHandlerMapping在各自的模块中。这个 添加来自每个类型和方法级别的注释对的值 到一个公司的配置

这意味着您的CORS设置将添加到

如果您使用的是Spring安全性,则需要这样做,以便使用您的CorsConfiguration。下面是一个小例子

   protected void configure(HttpSecurity http) throws Exception {
        http
            .cors()
            ...
    }

添加要使用的CorsFilter。如果名为corsFilter的bean 前提是使用了过滤网。否则,如果CorsConfiguration源为 定义,然后使用该公司配置。否则,如果Spring MVC 在类路径上使用HandlerMappingIntrospector

注意,如果您正在发送带有请求(cookies)的凭据,则需要将其添加到CORS设置中

@CrossOrigin(allowCredentials = "true")

解决方案是对WebTestClient使用以下配置:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureWebTestClient

class MyTestClass {

    @Autowired
    private WebTestClient webTestClient;

    @Test
    void corsTest() {
        ResponseSpec response = webTestClient.get()
                .uri("/cors-enabled-endpoint")
                .header("Origin", "http://any-origin.com")
                .exchange();

        response.expectHeader()
                .valueEquals("Access-Control-Allow-Origin", "*");
    }

}
我还需要添加
springbootstarterweb
依赖项,这很奇怪,因为我只使用Webflux。但如果没有它,测试仍然会失败,出现
IllegalArgumentException:实际请求方案不能为null

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
</dependency>

org.springframework.boot
SpringBootStarterWeb

现在,测试是绿色的

对于我来说,在不添加spring starter web依赖项的情况下,实际有效的方法是使用web筛选器,并在http方法为选项时强制返回

@Configuration
public class CorsGlobalConfiguration implements WebFilter {


@Override
public Mono<Void> filter(ServerWebExchange serverWebExchange,
                         WebFilterChain webFilterChain) {
    ServerHttpRequest request = serverWebExchange.getRequest();
    ServerHttpResponse response = serverWebExchange.getResponse();
    HttpHeaders headers = response.getHeaders();
    headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
    headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "POST, GET, PUT, OPTIONS, DELETE, PATCH");
    headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
    headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "*");
    headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*");
    headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "18000L");
    if (request.getMethod() == HttpMethod.OPTIONS) {
        response.setStatusCode(HttpStatus.OK);
        return Mono.empty();//HERE
    }
    return webFilterChain.filter(serverWebExchange);
}


}
@配置
公共类CorsGlobalConfiguration实现WebFilter{
@凌驾
公共Mono筛选器(ServerWebExchange ServerWebExchange,
网络过滤器链(网络过滤器链){
ServerHttpRequest请求=serverWebExchange.getRequest();
ServerHttpResponse response=serverWebExchange.getResponse();
HttpHeaders=response.getHeaders();
headers.add(HttpHeaders.ACCESS\u CONTROL\u ALLOW\u ORIGIN,“*”);
添加(HttpHeaders.ACCESS\u CONTROL\u ALLOW\u方法,“POST、GET、PUT、OPTIONS、DELETE、PATCH”);
添加(HttpHeaders.ACCESS\u CONTROL\u ALLOW\u凭证,“true”);
headers.add(HttpHeaders.ACCESS\u CONTROL\u ALLOW\u headers,“*”);
添加(HttpHeaders.ACCESS\u CONTROL\u EXPOSE\u headers,“*”);
headers.add(HttpHeaders.ACCESS\u CONTROL\u MAX\u AGE,“18000L”);
if(request.getMethod()==HttpMethod.OPTIONS){
response.setStatusCode(HttpStatus.OK);
返回Mono.empty();//此处
}
返回webFilterChain.filter(serverWebExchange);
}
}

@RichArt的解决方案是99%接近-但您不需要依赖性(spring boot starter web);因为它正在检查CORS,所以Spring似乎需要帮助了解您在测试中使用的方案和主机;它无法派生“scheme”(http)或URI较短的主机

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureWebTestClient
class MyTestClass {

    @Autowired
    private WebTestClient webTestClient;

    @LocalServerPort
    private Int lsp;

    @Test
    void corsTest() {
        ResponseSpec response = webTestClient.get()
                .uri("http://localhost" + lsp.toString() + "/cors-enabled-endpoint")
                .header("Origin", "http://any-origin.com")
                .exchange();

        response.expectHeader()
                .valueEquals("Access-Control-Allow-Origin", "*");
    }

}

非常感谢你的回答。在仔细阅读了它,并且再次阅读了文档之后,我仍然有同样的问题。实际上,我不使用Spring安全性。还有一件事:运行测试也会出现此错误:
2020-07-04 13:44:45.611错误17867---[parallel-1]o.s.w.s.adapter.httpwebhandleradopter:[38a66881]500 HTTP GET的服务器错误“/cors启用的端点”
java.lang.IllegalArgumentException:实际请求方案不能为null
这可能是根本原因,但我在internet上找不到帮助资源。您能帮忙吗?@RichArt请确保您将CrossOrigin放在发送请求的同一请求映射上。如果将CrossOrigin放在GET“/api/users”上,则CORS将仅对GET“/api/users”启用。您还可以将CrossOrigin置于控制器级别,然后CORS将可用于控制器中的所有请求映射,例如POST“/api/users”GET“/api/users”等。当然,这将取决于您在控制器中的CORS配置中允许的方法。
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureWebTestClient
class MyTestClass {

    @Autowired
    private WebTestClient webTestClient;

    @LocalServerPort
    private Int lsp;

    @Test
    void corsTest() {
        ResponseSpec response = webTestClient.get()
                .uri("http://localhost" + lsp.toString() + "/cors-enabled-endpoint")
                .header("Origin", "http://any-origin.com")
                .exchange();

        response.expectHeader()
                .valueEquals("Access-Control-Allow-Origin", "*");
    }

}