Fawfulcopter Fawfulcopter - 1 year ago 177
Javascript Question

CORS in AWS API Gateway + AWS Lambda

I am attempting to set up a POST lambda function using AWS Lambda and API Gateway. This POST should be callable from a modern browser using Javascript, so naturally, I need to enable CORS for this. Unfortunately, no matter what I do, the server is returning with a 400 error in Firefox. I have enabled CORS on my POST function in Gateway as well as set up an OPTIONS function with all the necessary headers, yet I still get this:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://ua1c36to9i.execute-api.ap-southeast-2.amazonaws.com/beta. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).


It's telling me that I'm not receiving an
Access-Control-Allow-Origin
header, which I can confirm by looking at the response in the Network tab:

Content-Length: 181
Content-Type: application/json
Date: Sun, 23 Apr 2017 03:39:10 GMT
Via: 1.1 d0d3075c33572544a6859ec75d2258a1.cloudfront.net (CloudFront)
X-Amz-Cf-Id: EEMUjL78Bf1PSwt4E4QGPgTLXSD8sehiUCgy-XA7TC_1cKv3jxs9Rg==
X-Cache: Error from cloudfront
X-Firefox-Spdy: h2
x-amzn-RequestId: 6943b9bd-27d6-11e7-aaae-f36ce836982f


The header
X-Cache: Error from cloudfront
seems to tell me that Lambda must be returning some kind of internal server error, and CORS is only enabled on Gateway for HTTP 200 requests. Indeed, my OPTIONS preflight returns with HTTP 200 OK, which shows that CORS seems to be enabled just fine. But I don't know how to capture an error with lambda and enable it for CORS so I don't know what my internal error could possibly be.

But what strikes me as curious is that if I use test-cors.org to test my POST function, it claims that I get an HTTP 200 OK. Even stranger, if I copy the exact code it generates to make the request and put it into a test HTML page on my local machine, I get HTTP 400 anyway. What's going on?

My ajax call:

var myData = JSON.parse(this.result);
console.log(result);
$.ajax({
type: "POST",
dataType: "json",
url: "https://ua1c36to9i.execute-api.ap-southeast-2.amazonaws.com/beta",
data: myData,
headers: {
"Content-Type":"application/json"
},
success: function (data) {
console.log(data);
},
error: function (error) {
console.log(error);
}
});


The function on AWS Lambda is currently configured to ignore the POSTed data and just return a hardcoded string, so the AJAX payload shouldn't matter.

Answer Source

You could try downloading the AWS APIG SDK and execute your AJAX call using the apigClient, and then compare headers with those from your script.

Take a look here: AWS API Gateway - CORS + POST not working

The setting of the header manually is particularly interesting based on your code:

headers: {
     "Access-Control-Allow-Origin": "*"
},

I also recommend trying:

data: JSON.stringify(myData)

This is also a good resource: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

Our API server had some issues with CORS on AWS Beanstalk and for us, it came down to correctly setting them. I remember requiring to clear my cache a few times also when we were initially setting it up.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download