skip to Main Content

I have an AWS lambda funtion. It works well and returns the following:

        return {
            statusCode: 200,
            headers: {
              'Access-Control-Allow-Origin': '*',
              'Access-Control-Allow-Credentials': true,
              'Access-Control-Allow-Headers': 'Content-Type',
              'Access-Control-Allow-Methods': 'OPTIONS, PUT, POST, GET, DELETE',
            },
            body: JSON.stringify('Success'),
        };

I created an API Gateway resource and a POST method within the resource.

I made the following configuration:

  1. For the resource I enabled CORS. I selected all methods and pressed save.
  2. In the method request section I set the Request body content tyoe as application/json and Model as Empty.
  3. Mapping templates within the Integration request is set like content type equals to ‘application/json’ and the Template body contains the following code:
{
    "company": "$input.json('$.company')",
    "newGoalGroups": $input.json('$.newGoalGroups')
}
  1. The response header within the Method response section contains 3 items: ‘Access-Control-Allow-Headers’, ‘Access-Control-Allow-Methods’ and ‘ Access-Control-Allow-Origin’.
  2. The content type within the Response body equals to ‘application/json’.

I tested the method in the API gateway console and it ran successfully.

I wanted to call the lambda function from the frontend (hosted at AWS amplify):

  try {
    console.log(`Url: ${apiGatewayUrl}${resourcePath}`);
    console.log(body);
    const response = await fetch(`${apiGatewayUrl}${resourcePath}`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(body),
    });
    
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }

    return response;
  } catch (error) {
    console.error('Error:', error);
  }

The parameter of the fetch is correct (I have a well working GET method within the same resource group. I copied the code from there)

The error what I got: TypeError: Failed to fetch

In the console of the browser, I see the following message:

Access to fetch at ‘https://xx.execute-api.eu-north-1.amazonaws.com/prod/GoalGroup’ from origin ‘https://dev.xy.amplifyapp.com’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: The ‘Access-Control-Allow-Origin’ header has a value ‘https://dev.xy.amplifyapp.com/’ that is not equal to the supplied origin. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

Within the same resource I have a GET, PUT and POST methods. The GET works well while PUT and POST run to the same error.

Please help how I can make PUT and POST work.

2

Answers


  1. Chosen as BEST ANSWER

    The error happened during the preflight. There is an OPTIONS method. Its header mapping was set including two errors:

    1. the methods contained only OPTIONS and GET. I added PUT and POST
    2. the origin contained a trailing slash. I removed it.

    After these two modifications my POST method works well.


  2. See this related question

    Is your browser sending an authorization header to the API Gateway when it makes the API request? If so, then you need to either disable authorization or add the appropriate headers to the Access-Control-Allow-Headers list. Also double check that the content type being requested is the same as what is being delivered (e.g. application/JSON for both).

    As for the difference in behavior between GET and POST/PULL, the default settings on browsers don’t block "simple" requests to cross-origin sites, and a GET request that meets certain criteria is considered simple.

    See https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests for info on the criteria that triggers CORS

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search