简体   繁体   中英

AWS CDK LambdaRestApi enable CORS issue

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. 在此处输入图像描述

  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. 在此处输入图像描述 在此处输入图像描述

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: ['*']
        }
});

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
  }


The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM