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

时间:2018-04-12 16:16:13

标签: java spring cors angular5 http-status-code-403

当我向服务器发送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);
    });
  }

获取方法有效,但Post没有。他们都在Swagger和Postman工作。我多次更改了POST方法。我的代码中的标题不起作用,但我解决了他们扩展到谷歌浏览器的问题。只有一个错误:

Response for preflight has invalid HTTP status code 403.

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

3 个答案:

答案 0 :(得分:5)

问题:

对于任何Cross-Origin 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");

答案 1 :(得分:2)

您需要确保Spring接受CORS请求

此外,如果您已应用Spring安全性并要求例如API的授权标头,则(仅在需要使应用程序支持CORS的情况下),您应该在授权中排除OPTIONS调用春天的安全配置文件。

会是这样的:

@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调用。

答案 2 :(得分: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("*");
            }
        };
    }

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