Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 5: Response for preflight has invalid HTTP status code 403

When I send a POST request to the server I get an error:

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.

The backend is written in Java Spring. My method for creating a test:

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 Method works, but Post doesn't. They both work in Swagger and Postman. I changed POST method many times. The headers in my code do not work, but I solved the problem with them expanding to Google Chrome. There was only an error:

Response for preflight has invalid HTTP status code 403.

It seems to me that this is not Angular problem. Please tell me how I or my friend (who wrote the backend) can solve this problem.

like image 518
Vitaliy Pogoretsky Avatar asked Jan 03 '23 13:01

Vitaliy Pogoretsky


2 Answers

PROBLEM :

For any Cross-Origin POST request, the browser will first try to do a OPTIONS call and if and only if that call is successful, it will do the real POST call. But in your case, the OPTIONS call fails because there is no 'Access-Control-Allow-Origin' response header. And hence the actual call will not be done.

SLOUTION :

So for this to work you need to add CORS Configuration on the server side to set the appropriate headers needed for the Cross-Origin request like :

  • 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");
like image 105
Raj Rajeshwar Singh Rathore Avatar answered Jan 05 '23 16:01

Raj Rajeshwar Singh Rathore


You need to ensure that the Spring accept CORS requests

Also if you have applied Spring security & require authorization headers for example for your API, then (only if you need to make your app support CORS) you should exclude the OPTIONS calls from authorization in your spring security configuration file.

It will be something like this:

@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,"/**")

Note:

In production, probably it is better to use reverse proxy (like nginx) & not allow the browsers to call your API directly, in that case, you don't need to allow the OPTIONS calls as shown above.

like image 39
Ahmed Elkoussy Avatar answered Jan 05 '23 16:01

Ahmed Elkoussy