Reputation: 2198
I have a CDK project with Api Gateway backed with lambda function. I have a domain mydomain.com
which points to my CloudFront distribution and a subdomain api.mydomain.com
that points to my REST API. In the browser when I hit POST api.mydomain.com/api/sendEmail
I get CORS issue. I've tried already everything and none of them actualy enables CORS. This is the setting that might be relevant for my case but I can't find a way to enable it in CDK.
const api = new apigw.LambdaRestApi(this, 'APIGateway', {...});
const items = api.root.addResource('sendEmail');
items.addMethod('POST', new apigw.LambdaIntegration(mailerLambdaFunction), {
methodResponses: [{
statusCode: '200',
responseParameters: {
"method.response.header.Access-Control-Allow-Headers": true,
"method.response.header.Access-Control-Allow-Methods": true,
"method.response.header.Access-Control-Allow-Credentials": true,
"method.response.header.Access-Control-Allow-Origin": true,
}
}]
})
{
body: JSON.generate(message: 'Thank you for reaching out! I\'ll contact you as soon as I can'),
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
},
isBase64Encoded: false
}
defaultCorsPreflightOptions
(answer here AWS CDK API Gateway enable Cors) but it doesn't work.UPDATE
I went ahead and clicked Enable CORS and here's what happened. It failed to add Access-Control-Allow-Origin Method Response Header to POST method. I added it in my code. I can't, however, add Integration Response, it's grayed out.
Upvotes: 0
Views: 1652
Reputation: 1193
It doesn't seem like you have a route to handle OPTIONS requests. You need to add that and provide the same headers as your Lambda functions to allow POST api.mydomain.com/api/sendEmail
Did you add defaultCorsPreflightOptions
like this? This approach works for me.
const api = new apigw.LambdaRestApi(this, 'APIGateway', {
...,
defaultCorsPreflightOptions: {
allowOrigins: ['*'],
allowMethods: ['*'],
allowHeaders: ['*']
}
});
Upvotes: 1
Reputation: 2198
I looked at my lamda logs and noticed I wasn't sending a propoer JSON from my front-end application to the backend lambda. Previously, I was sending AJAX request like this:
var request = $.ajax({
url: url,
crossDomain: true,
method: "POST",
data: {
data1: 'Test1',
data2: 'Test2',
data3: 'Test3'
},
dataType: "json",
contentType: 'application/json'
});
I changed it to:
var data = {
name: $('#requestername').val(),
email: $('#requesteremail').val(),
message: $('#requesterMessage').val()
}
/* Send the form data using ajax */
var request = $.ajax({
url: url,
crossDomain: true,
method: "POST",
data: JSON.stringify(data),
dataType: "json",
contentType: 'application/json'
});
Also, I realised that I wasn't returning proper CORS headers from my backend API proxy integration when an error occurs. That's why I was getting CORS issue - wrong JSON in request and error while parsing the actual request body. Both success and error responses should return CORS headers.
# success
{
body: JSON.generate(message: 'Message'),
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Headers': 'Origin,Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token',
'Access-Control-Allow-Methods': 'GET,OPTIONS,POST',
'Access-Control-Allow-Origin': '*'
},
isBase64Encoded: false
}
# error
{
body: JSON.generate({ error: error.message }),
statusCode: 400,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Headers': 'Origin,Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token',
'Access-Control-Allow-Methods': 'GET,OPTIONS,POST',
'Access-Control-Allow-Origin': '*'
},
isBase64Encoded: false
}
Upvotes: 0