CORS preflight failed when all headers are wildcard (Lambda)

I’m trying use JavaScript, Lambda and SES to generate an email from a contact form. The code works when I test it from the Lambda console, but when I invoke it with HTTP it doesn’t work, even though I have confirmed the data is the same and the appropriate headers are allowed.

Here are the console errors in the browser:

Console errors

Here’s my Lambda function:

import boto3
import json

ses = boto3.client('ses')

def lambda_handler(event, context):

    name = event['name']
    email = event['email']
    phone_number = event['phone_number']
    message = event['message']

    # Construct the email message
    subject = f"New message from {name}"
    body = f"From: {name}nEmail: {email}nPhone: {phone_number}nMessage: {message}"
    sender = '[email protected]'
    recipient = '[email protected]'

    # Send the email using AWS SES
    response = ses.send_email(
        Source=sender,
        Destination={
            'ToAddresses': [
                recipient,
            ]
        },
        Message={
            'Subject': {
                'Data': subject,
                'Charset': 'UTF-8'
            },
            'Body': {
                'Text': {
                    'Data': body,
                    'Charset': 'UTF-8'
                }
            }
        }
    )

    return {
        'statusCode': 200,
        'headers': {
            'Access-Control-Allow-Headers': '*',
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': '*'
        },
        'body': json.dumps('Email sent successfully!')
    }

Here’s my JavaScript:

const formEl = document.querySelector(".contact_form");

formEl.addEventListener('submit', event => {
    event.preventDefault()

    const formData = new FormData(formEl);

    const data = Object.fromEntries(formData);


    fetch('https://myapigatewayuri/prod/contact-form', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
    })
    .then( response => {
        console.log('Here is the response:')
        console.log(response);
        if (response.status === 200) {
            formEl.reset();
            window.alert("Your message was sent successfully. Thank you for reaching out!")
        } else if (response.status !== 200) {
            window.alert("There was a problem sending your message.")
        }
    })
    
});

Here’s the data that is getting sent in the request:

{
'name': 'test name', 
'phone_number': '12345678', 
'email': '[email protected]', 
'message': 'test message'
}

CloudWatch Logs shows this error:

  "errorMessage": "'name'",
    "errorType": "KeyError",
    "stackTrace": [
        "  File "/var/task/lambda_function.py", line 16, in lambda_handlern    name = event['name']n"
    ]

This error does not occur when testing in the console with the same data.

If I change the variable assignment to use the get() method like this:


   name = event.get('name')
    email = event.get('email')
    phone_number = event.get('phone_number')
    message = event.get('message')

The CORS error goes away and the email generates but all the values are ‘none’.

I would have thought this indicates that the data isn’t making it to the function at all, however when running this version of the function I get the following output in CloudWatch logs:


(e5f7444e-a6a5-4b8f-8f47-8f586a342a4a) Method request body before transformations: {
    "name": "test name",
    "phone_number": "12345678",
    "email": "[email protected]",
    "message": "test message"
}


I can’t figure out what is going on here and I’ve run out of things to do to try and narrow down the problem. Any help appreciated.