Search code examples
javascriptcorsaws-api-gateway

CORS error only when using a URL query string parameter


I have a GET method on a resource using AWS API Gateway, with a URL query string parameter, that isn't required. I have enabled CORS for the resource, and the OPTIONS method is present, and working for other authorized API calls.

If I call the GET method from the frontend without the string parameter, everything works fine, without issues. When I run a 'test' via the API Gateway Console with a string parameter, everything works fine. If I call the method from the frontend with a string parameter, I get a CORS error:

Access to fetch at 'myAPIURL' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

Other information about the API:

  • It's used to trigger a lambda function that fetches some DynamoDB records
  • No other method has a CROS error, but no other methods use a string parameter
  • Some methods use a path parameter, and work fine
  • Authorization is through Cognito

My frontend API call is as follows:

fetchInvoices(strParam){
    const returnedData = null;
    const url = invokeURL + encodeURIComponent("invoicess?invYear=" + strParam);
    fetch(url, { headers: { "Authorization": token } })
        .then(response => { 
        return response.json() 
    })
    .then(jsonData => {
        returnedData = jsonData;
    })
    .catch(e => {
        console.log(e)
    })
    return returnedData
}

Why is the string parameter causing a CORS error?


Solution

  • Your issue lies in the following line:

    const url = invokeURL + encodeURIComponent("invoicess?invYear=" + strParam);
    

    Let's check an example, let's say that invokeURL = 'https://example.com/' and strParam = '2024'. Given this, your url variable would actually be:

    https://example.com/invoicess%3FinvYear%3D2024
    

    The problem now is that your API Gateway will see invoicess%3FinvYear%3D2024 as the path of the URL and not invoicess which is why you're getting your CORS error.


    A solution would be to change how you're passing your query parameters:

    const params = new URLSearchParams({ invYear: strParam });
    const url = `${invokeURL}invoicess?${params.toString()}`;
    

    URLSearchParams already does the URI encoding necessary so you don't have to worry about it.