Angular 6 - Spring MVC :: Options preflight request throws 500 internal Server Error

Posted

技术标签:

【中文标题】Angular 6 - Spring MVC :: Options preflight request throws 500 internal Server Error【英文标题】: 【发布时间】:2020-03-28 21:21:30 【问题描述】:

意图:在 Angular 中使用通过基于 SpringMVC 的 Web 应用程序公开的 REST API。两者都在不同的主机上运行

问题

虽然我请求的 API 是 GET 请求,但 Angular幕后首先向 REST API SpringMVC 服务器发出 OPTIONS 请求。这会引发 500 服务器错误(请参阅下面的 CURL 输出)。

尝试使用 Postman 工具 (GET 请求) 访问相同的 API,令人惊讶的是它提供了所需的输出 (即也提供了 Access-Control-Allow-Origin 标头) 没有任何错误,但 OPTIONS 请求引发 500 服务器错误。

我正在使用的技术栈

Angular 6(在 NodeJS 上运行) Spring MVC 4.3.6.RELEASEno Spring 安全明确配置)[Java config 基于 Spring 配置] Jetty-Runner 9.4.1(运行 Spring MVC webapp 的 WAR 文件)。

Angular 收到的错误消息:

Access to XMLHttpRequest at 'http://localhost:8080/v1/create' 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.

代码片段:

Angular 代码:

public createDomainObj()            
    return this.http.post('http://localhost:8080/v1/create', request body parameter)

SpringMVC 代码:

@ResponseBody
@RequestMapping(value = "/v1/create", method = RequestMethod.POST)
@AccessController(accessLevel = "Anonymous")
public <APIResponseModelClass> anAPIMethod(@RequestBody param1, param2) 
    //code logic 
    return <obj>;

已经尝试过的内容:

SpringMVC 中的 CORS 过滤器,所有注释组合,但没有运气。

也尝试过以下链接中提到的建议,但均未成功:

https://www.baeldung.com/spring-security-cors-preflight

How to add Access-Control-Allow-Origin to jetty server

CURL 能够重现问题:

请求

curl -H "Origin:*" -H "Access-Control-Request-Method: GET, POST, PUT, DELETE" 
-H "Access-Control-Request-Headers: X-Requested-With" 
-X OPTIONS --verbose  http://localhost:8080/v1/create

回应

Trying 127.0.0.1...
 Connected to localhost (127.0.0.1) port 8080 (#0)
 OPTIONS /v1/create HTTP/1.1
 Host: localhost:8080
 User-Agent: curl/7.47.0
 Accept: */*
 Origin:*
 Access-Control-Request-Method: GET, POST, PUT, DELETE
 Access-Control-Request-Headers: X-Requested-With
 Content-Length: 392
 Content-Type: application/x-www-form-urlencoded

 upload completely sent off: 392 out of 392 bytes
 HTTP/1.1 500 Server Error
 Connection: close
Server: Jetty(9.4.2.v20170220)
Closing connection 0


那么,如何让 Angular 使用 SpringMVC 中具有 OPTIONS 预检方面的 REST API?

【问题讨论】:

您在使用spring-security 吗?尝试阅读spring.io/guides/gs/rest-service-cors 你能添加你失败的代码吗?? 【参考方案1】:

我可以说一下问题, CORS:Response to preflight request doesn't pass access control, 有两种类型的请求, 1) 简单 有一些标准,简单交换 cors 标头、允许的方法、标头、内容类型 2) 预检 那些不符合简单请求标准的是预检,例如, 我们向服务器发送 DELETE 请求。浏览器发送带有标题的 OPTIONS 请求,其中包含有关我们发出的 DELETE 请求的信息。

OPTIONS /users/:id 
Access-Control-Request-Method: DELETE 

简单的解决方法是您可以删除或更改任何不需要的复杂标头。

Header set Access-Control-Allow-Origin "*" 设置这将适用于简单的 CORS 请求,因此对于具有自定义标头值的更复杂的请求将不起作用,这就是它检查服务是否接受请求的浏览器的预检机制, 请记住,它包括,

Access-Control-Request-Headers
Access-Control-Request-Method
Access-Control-Allow-Origin

看来您需要在 http configure thats cors filter 中添加 cors, 启用 cors 的不同方式, 1)控制器方法CORS配置

  @CrossOrigin(origins = "http://localhost:9000")
  @GetMapping("/greeting")
  public Greeting greeting(@RequestParam(required=false, defaultValue="World") String name) 
    System.out.println("==== in greeting ====");
    return new Greeting(counter.incrementAndGet(), String.format(template, name));
  

2) 全局 CORS 配置

  public WebMvcConfigurer corsConfigurer() 
    return new WebMvcConfigurer() 
      @Override
      public void addCorsMappings(CorsRegistry registry) 
        registry.addMapping("/greeting-javaconfig").allowedOrigins("http://localhost:9000");
      
    ;
  

3) 启用webSecurity,尝试添加http.cors()

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 
    @Override
    protected void configure(HttpSecurity http) throws Exception 
        // ...
        http.cors();
    

【讨论】:

我用失败代码更新了我的问题,提供了更多关于问题的详细信息,请立即检查并提供您的想法? @AmrutaShiralkar 好问题

以上是关于Angular 6 - Spring MVC :: Options preflight request throws 500 internal Server Error的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security + Angular JS + Spring MVC Rest

Spring 5 MVC Angular 5 App投掷404错误

在 Angular 2 和 Spring MVC 中上传带有其他表单字段的文件

带有angular2的spring mvc(rest)导致302暂时移动

来自 angular-ui-router 和 spring mvc 的请求映射

从现有数据库生成 Angular 5 和 Spring mvc CRUD 应用程序 [关闭]