Be an AWS lambda expert No.3 - How to handle CORS errors when calling AWS API Gateway endpoint from frontend


We have developed a AWS lambda function, then we put it online by using AWS API gateway in our previous blogs:
https://www.datasciencebyexample.com/2022/09/01/2022-09-01-1/
https://www.datasciencebyexample.com/2022/09/02/2022-09-02-1/

We could also test the API and verify it is working as what we expect, things really look awesome.

So we are ready to send the API endpoint to our frontend and call it from the website.

As soon as we did that, we found some CORS errors like this:

Error message:
Access to XMLHttpRequest at ‘https://xxx.execute-api.us-east-1.amazonaws.com/prod/' from origin ‘https://www.datasciencebyexample.com' has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

The CORS error stands for Cross-Origin Resource Sharing (CORS) error. By default, the server side and web side can’t be talking from different domains.
So we need to relax this requirement from both sides.

Enable CORS on AWS API gateway

First, on the server side, we need to make sure the response from the server side, i.e. the API, should have the header including ‘Access-Control-Allow-Origin’ key, to tell which domain is allowed to call the API. We can put specific domain to be the value for the value, or ‘*’ to stand for all sites are allowed. Notice that this header is provided by the API side, not from the frontend side.

With AWS API gateway, one can check the official guide here,
https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html, or just follow the following steps:

  1. Sign in to the API Gateway console at https://console.aws.amazon.com/apigateway.

  2. In the API Gateway console, choose an API under APIs.

  3. Choose a resource under Resources. This will enable CORS for all the methods on the resource. Alternatively, you could choose a method under the resource to enable CORS for just this method.

  4. Choose Enable CORS from the Actions drop-down menu.
    and Choose Enable CORS

  5. In the Enable CORS form, don’t need to change anyting, just use the default suggestions, basicaly they are:

    1. In the Access-Control-Allow-Headers input field, type a static string of a comma-separated list of headers that the client must submit in the actual request of the resource. Use the console-provided header list of Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token or specify your own headers.

    2. Use the console-provided value of ‘*’ as the Access-Control-Allow-Origin header value to allow access requests from all domains, or specify a named domain to all access requests from the specified domain.

    Choose Enable CORS and replace existing CORS headers.

  6. Last but not least, remember to deploy the API again, otherwise it might not take effect.

Here is screen shot of what described in the above steps:

We can check if the CORS setting is working by calling the API using requests library in python, and print out the headers from response:

Calling API using javascript fetch

After verifing the header has the “Access-Control-Allow-Origin” key and value from the response header, we are sure the CORS is all set up on the server side.
To call the endpoint on the frontend, we don’t need to much work, just find the method that you like.

Here is an example of calling the POST endpoint using fetch in javascript:

function CORSexample(input) {

// call api
// POST request using fetch()
fetch("https://xxx.execute-api.us-east-1.amazonaws.com/prod/", {
method: "POST",
// Adding body or contents to send
body: JSON.stringify({
"data":{"query":input}
}),

// Adding headers to the request if necessary
headers: {
"Content-type": "application/json; charset=UTF-8"
}
})

// Converting result to JSON
.then(response => response.json())

.then(function(result)
{
console.log(result)
// in some older jquery version, one has to parse the json to be object
// it's not necessary in new versions, just try it or not
//var result = $.parseJSON(result)

// continue other custome stuff you have

}

}).catch(error => console.error('Error:', error));



}

Author: robot learner
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source robot learner !
  TOC