0

EDIT2: GETs don't send JSON data. That's my problem. Working on sending it at URL data. It's not letting me delete this post either.

EDIT: I figured out that it's not a preflight problem using developer tools and the network tab. The issue is that the JSON data is not being sent for the GET but it is for the POST. The lack of the Origin header was because the lambda was crashing when it was trying to read the JSON data from the request. Added a try/except block to catch that but I have no clue why the data isn't being sent.

Browser claims No 'Access-Control-Allow-Origin' header is present on the requested resource.

The code below is an AWS Lambda which is behind an AWS REST API Gateway.

POSTs work but GETs throw this error - Access to XMLHttpRequest at 'https://my_url.amazonaws.com/dev/quark/customers' from origin 'http://localhost:8081' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

They're configured exactly the same and logs(CloudWatch) show that the header is being set properly.

import logging

def lambda_handler(event, context):
    logging.getLogger().setLevel(logging.INFO)
    logging.info(event["headers"]["Origin"])
    response = {
            'statusCode': 200,
            'headers': 
            {
            'Access-Control-Allow-Headers': 'Content-Type, Authorization',
            'Access-Control-Allow-Credentials': True,
            'Access-Control-Allow-Origin': event["headers"]["Origin"],
            'Access-Control-Allow-Methods': 'POST,GET,DELETE,PATCH'
            },
            'isBase64Encoded':False,
            'body': ""
        } 
    
    logging.info(response)
    return response

Both of these CURLs work but only the POST works in the browser(using JS for that, included for reference)

curl -X POST -H 'Authorization: Basic API_AUTH_KEY' -H "Cache-Control: no-cache" https://my_url.amazonaws.com/dev/quark/customers -d @./data_for_testing/customer.json

curl -X GET -H 'Authorization: Basic API_AUTH_KEY' -H "Cache-Control: no-cache" https://my_url.amazonaws.com/dev/quark/customers -d @./data_for_testing/customer.json


    function send()
    {    
        var ItemJSON;
    
        ItemJSON = '{    "customer_info":    {        "customer_shortname":"WU2",        "deploy_pending": "ams,arn,dal,fra,gru,iad,lax,lcy,lga,nrt,sin,sjc,syd"    },    "object_type":"customer"}';
    
        URL = "https://my_url.amazonaws.com/dev/quark/customers" 
    
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = callbackFunction(xmlhttp);
        xmlhttp.open("GET", URL, false);
        xmlhttp.setRequestHeader("Content-Type", "application/json");
        //xmlhttp.setRequestHeader('Authorization', 'Basic API_AUTH_KEY'); //in prod, you should encrypt user name and password and provide encrypted keys here instead 
        xmlhttp.onreadystatechange = callbackFunction(xmlhttp);
        xmlhttp.send(ItemJSON);
        alert(xmlhttp.responseText);
        document.getElementById("div").innerHTML = xmlhttp.statusText + ":" + xmlhttp.status + "<BR><textarea rows='100' cols='100'>" + xmlhttp.responseText + "</textarea>";
    }
    
    function callbackFunction(xmlhttp) 
    {
        //alert(xmlhttp.responseXML);
    }
    </script>
    <html>
    <body id='bod'><button type="submit" onclick="javascript:send()">call</button>
    <div id='div'>
    
    </div></body>
    </html>

Authorization is disabled until I can get the CORS response to work properly.

I've tried both Chrome and Firefox to see if they get the same behavior and they do.

I'm only setting the Origin header to what's in the request for dev purposes, an asterisk does not make it work.

I've been doing a bunch of reading and since this is a GET without authorization, it should not need the preflight but it seems to still access it when I make the GET calls.

[pic of console/network tab][1] [1]: https://i.stack.imgur.com/rolGy.png

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
J Kast
  • 9
  • 4
  • _"and since this is a GET without authorization, it should not need the preflight "_ - it should in this instance, because you are sending `content-type: application/json` - which makes this _not_ a "simple request" that would not require a preflight any more, see https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests But the error message you are getting does not say anything about a preflight request failing, which it rather should, if that was the issue. – CBroe Jul 07 '22 at 14:22

1 Answers1

0

GET requests from the browser will get a pre-flight request first. Try adding "OPTIONS" to your list in Access-Control-Allow-Methods. Also make sure any rules / firewall in front of the request is allowing OPTIONS queries.

Matt S
  • 14,976
  • 6
  • 57
  • 76
  • 1
    Not sure why this was downvoted. the OPTIONS request getting blocked was my initial thought as well. – jordanm Jul 06 '22 at 23:06
  • 1
    I added OPTIONS and it didn't change anything – J Kast Jul 07 '22 at 00:48
  • 1
    If it was the preflight request that failed, then the client-side error message should explicitly say so, _"Response to preflight request doesn't pass access control check"_ or similar. But that does not appear to be the case here. – CBroe Jul 07 '22 at 14:19