Angular 5:预检响应具有无效的 HTTP 状态代码 403

Posted

技术标签:

【中文标题】Angular 5:预检响应具有无效的 HTTP 状态代码 403【英文标题】:Angular 5: Response for preflight has invalid HTTP status code 403 【发布时间】:2018-09-22 21:27:50 【问题描述】:

当我向服务器发送 POST 请求时出现错误:

Failed to load http://localhost:8181/test: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 403.

后端是用 Java Spring 编写的。 我创建测试的方法:

createTest() 
    const body = JSON.stringify(
      'description': 'grtogjoritjhio',
      'passingTime': 30,
      'title': 'hoijyhoit'
    );

    const httpOptions = 
      headers: new HttpHeaders(
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        
      )
    ;

    return this._http.post(`$this._config.API_URLS.test`, body, httpOptions)
      .subscribe(res => 
        console.log(res );
      , error => 
        console.log(error);
    );
  

Get 方法有效,但 Post 无效。他们都在 Swagger 和 Postman 工作。我多次更改 POST 方法。我的代码中的标头不起作用,但我解决了将它们扩展到 Google Chrome 的问题。只有一个错误:

Response for preflight has invalid HTTP status code 403.

在我看来,这不是 Angular 问题。请告诉我我或我的朋友(编写后端)如何解决这个问题。

【问题讨论】:

您能否在此处分享 chrome 网络选项卡的完整详细信息,因为这将有助于查看是否有合适的标头出现? 【参考方案1】:

我最近在使用 Angular 时遇到了完全相同的问题。发生这种情况是因为某些请求正在触发预检请求,例如。 PATCHDELETEOPTIONS 等。这是 Web 浏览器中的安全功能。它适用于 Swagger 和 Postman 仅仅是因为他们没有实现这样的功能。要在 Spring 中启用 CORS 请求,您必须创建一个返回 WebMvcConfigurer 对象的 bean。不要忘记@Configuration,以防你为此增加了额外的课程。

    @Bean
    public WebMvcConfigurer corsConfigurer() 
        return new WebMvcConfigurer() 
            @Override
            public void addCorsMappings(CorsRegistry registry) 
                registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*")
                        .allowedHeaders("*");
            
        ;
    

当然,您可以根据自己的需要进行调整。

【讨论】:

【参考方案2】:

您需要确保 Spring 接受 CORS 请求

此外,如果您已应用 Spring 安全性并需要授权标头,例如您的 API,那么 (仅当您需要使您的应用支持 CORS 时)您应该在您的授权中排除 OPTIONS 调用spring 安全配置文件。

会是这样的:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 

  @Override
  protected void configure(HttpSecurity http) throws Exception 

  @Override
  public void configure(WebSecurity web) throws Exception 
    // Allow OPTIONS calls to be accessed without authentication
    web.ignoring()
        .antMatchers(HttpMethod.OPTIONS,"/**")

注意:

在生产中,可能最好使用反向代理(如 nginx)并且不允许浏览器直接调用您的 API,在这种情况下,您不需要像上图那样允许 OPTIONS 调用。

【讨论】:

【参考方案3】:

问题:

对于任何跨域 POST 请求,浏览器将首先尝试执行 OPTIONS 调用,当且仅当该调用成功时,它才会执行真正的 POST 调用。但是在您的情况下, OPTIONS 调用失败,因为没有 'Access-Control-Allow-Origin' 响应标头。因此不会完成实际调用。

SLOUTION:

因此,要使其正常工作,您需要在服务器端添加 CORS 配置,以设置跨域请求所需的适当标头,例如:

response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Headers", "content-type, if-none-match"); response.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS"); response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Max-Age", "3600");

【讨论】:

我不知道为什么这条狗咬我这么多次。但我总是忘记设置 CORS 属性的“IN THE RESPONSE”标题。如果您在“REQUEST”标题上这样做,您将继续遇到问题...... 发生在我们最好的人身上。

以上是关于Angular 5:预检响应具有无效的 HTTP 状态代码 403的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2 - 预检响应具有无效的 HTTP 状态代码 401

预检响应具有无效的 HTTP 状态代码 403 + angular 2 + Java Spring boot

通过基本身份验证访问 REST 的 Angular2 抛出“预检响应具有无效的 HTTP 状态代码 401”

预检响应具有无效的 HTTP 状态代码:401 角度

预检响应在 Angular Js1 和 Webapi 2 上具有无效的 HTTP 状态代码 405

AngularJS HTTP 标头配置。预检响应具有无效的 HTTP 状态代码 401