Spring 引导:即使使用了@CrossOrigin,CORS 策略也已阻止从源 FRONTEND 访问 BACK_END' 处的 XMLHttpRequest

Spring Boot : Access to XMLHttpRequest at BACK_END' from origin FRONTEND has been blocked by CORS policy even when @CrossOrigin is used

我有一个标有@CrossOrigin(origins = "*", allowedHeaders = "*")的restcontroller。但是,尽管 @CrossOrigin(origins = "*", allowedHeaders = "*") 在控制器级别,我的请求还是被 CORS 策略阻止了。

Access to XMLHttpRequest at 'http://localhost:8080/api/v1/foo/bar' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

下面是代码的概要

import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.CrossOrigin;
import javax.mail.MessagingException;
import javax.validation.Valid;
import java.io.UnsupportedEncodingException;

@CrossOrigin(origins = "*", allowedHeaders = "*")
@RestController
@RequestMapping(path="/api/v1")
@AllArgsConstructor
public class SomeRestController {

    @Autowired
    private SomeService someService;


    @PostMapping(path="/foo/bar")
    public ResponseEntity<RespObject> dosomething(@Valid @RequestBody RequestDTO requestDTO) 
    .
    .
    .
    //somecode
    }
}

正在从 Angular Ui 应用调用 api。

APIService.ts

create(candidateInititationDto: CandidateInitiationDTO) {
    return this.httpClient.post<RespObject>(
      "http://localhost:8080/api/v1/foo/bar",
      requestDTO
    );
  }
  1. 到目前为止,这是该微服务中唯一的控制器,我已经尝试了 @CrossOrigin(origins = "", allowedHeaders = "") ,@ 的所有可能组合CrossOrigin,@CrossOrigin(origins = "*") 在控制器级别和方法级别。

这是唯一一个 @CrossOrigin 不起作用的微服务。它在所有其他微服务中运行良好。

尝试将此 Bean 添加到您的控制器:

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurerAdapter() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**").allowedOrigins("*");
        }
    };
}

例如:

@RestController
@RequestMapping(path="/api/v1")
@AllArgsConstructor
public class SomeRestController {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedOrigins("*");
            }
        };
    }

    @Autowired
    private SomeService someService;


    @PostMapping(path="/foo/bar")
    public ResponseEntity<RespObject> dosomething(@Valid @RequestBody RequestDTO requestDTO) 
    .
            .
            .
    //somecode
}

尝试删除 origins 和 allowedHeaders 并简单地使用

@CrossOrigin

这也将允许所有请求。

终于解决了问题。显然,在重构代码时,包名称发生了变化,并且它没有被包扫描识别出来。 Spring 它没有抛出 404 ,而是在预检请求时失败了。

我调试的步骤。

  1. 删除所有其他控制器

  2. 保留一个尝试调试的控制器和方法。

  3. 当我尝试用 postman 打它时,它失败了,那时我们才知道它失败的原因。
  4. 为了防止这种灾难再次发生集成测试已经到位
  5. @CrossOrigin(origins = "", allowedHeaders = "") ,@CrossOrigin。以上所有选项都可以。
  6. 最安全的方法是拥有全局 CORSS 过滤器和白名单 orings 并使其可配置。