skip to Main Content

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.
enter image description here

  1. I tried adding response methods to my resource
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,
        }
      }]
    })
  1. I’ve tried returning a predefined response from my lambda function
{
    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
  }
  1. I’ve tried adding 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.
enter image description here
enter image description here

2

Answers


  1. Chosen as BEST ANSWER

    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
      }
    
    
    

  2. 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: ['*']
            }
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search