Angular app sends just option request without post

2019-09-20 13:25发布

问题:

This question already has an answer here:

  • How does Access-Control-Allow-Origin header work? 13 answers

I'm making an app in angular 7 that connects to API that I wrote in python. I want to send a text in POST request and API does some nlp stuff and returns the result. API is using RestPlus and is hosted on GCP App Engine. So in angular I have this code:

posts: any;
readonly ROOT_URL = 'XXX';
const httpOptions = {
  headers: new HttpHeaders({
    'Access-Control-Allow-Origin': '*',
    'Content-Type': 'application/json',
    'X-API-KEY': 'X',
  })
};
const data: any = {
  "article": this.text
};
this.posts = this.http.post(this.ROOT_URL, data, httpOptions);

this.text is a value I get from form and I've already checked if it's valid. X-API-KEY is a token I set in API.

In console I get:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at XXX. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at XXX. (Reason: CORS request did not succeed).

I tried sending a post request to postb.in to test it and got the same errors. And postb.in shows that it only received OPTION requests.

回答1:

Cross origin request means that you are trying to make an API call to a server which is not your origin (this server is not rendering the front-end/client-end).

Example: If http://localhost/dummy-app delivers the front-end and you are trying to make an API call from this front-end to http://localhost:3000/dummy-api, it will result in a CORS issue.

Resolutions:

  • Render the front-end from the server where the API end point exists. This is only a technical solution and may not be a good architecture or not even possible at times.
  • Allow CORS in server. (Not highly recommended)
  • Use a middleware server to render your front end. This server can have an API endpoint through which you can pass the request to desired API. CORS issue appears to be a blocking by the browser and appears only when an external API is called from front-end. You can call an API in the middleware server which then further calls the external API.
  • Recommended : Use your web server to do the job. For example, create a new route in Nginx which proxy passes your request to the API.

    location /api{ proxy_pass http://localhost:3000 }

In this method http://localhost/dummy-app can call the API as http://localhost/api/dummy-api.