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.