0

I am trying to make a fetch (method POST) from my s3 hosted static website to one of my lambda functions, which runtime language is nodejs, through API Gateway.

Following the snippets about HTML post form, the JS script that does the post request converting the form data in json, and my nodejs lambda function.

<form name='form' id="myForm">
            <div id=whatpageisit><a href='index.html'>LOGIN</a>SIGNUP  </div>
            
            <p> <label>Username <input type='text' name='username' value=''></label> </p>
            <p> <label>Email <input type='email' name='email' value=''></label> </p>
            <p> <label>Password <input type='password' name='password' value=''></label> </p>
            <p> <label>Conferma Password <input type='password' name='conferma_password' value=''></label> </p>
            
            <p> <div id="submit"><label>&nbsp;<input type='submit'></label></div> </p>
        </form>

------------- JS

<script> // https://gomakethings.com/serializing-form-data-with-the-vanilla-js-formdata-object/
            document.addEventListener('submit', function (event) {
                event.preventDefault(); 
                
                fetch('', {
                    //mode:"no-cors",
                    method: 'POST',
                    body: JSON.stringify(Object.fromEntries(new FormData(event.target))),
                    headers: {
                        'Content-type': 'application/json; charset=UTF-8'
                    }
                }).then(function (response) {
                if (response.ok) {
                    return response.json();
                }
                return Promise.reject(response);
                }).then(function (data) {
                    console.log(data);
                }).catch(function (error) {
                    console.warn(error);
                });
            });
        </script>

--- LAMBDA FUNCTION

    exports.handler =  (event, context, callback) => { 
  context.callbackWaitsForEmptyEventLoop = false; 
      pool.getConnection(function(err,connection){
        var user = event.body.username;
        var email = event.body.email;
        var password = event.body.password;
        var sql0 = "INSERT INTO users VALUES ('"+user+"','"+email+"','"+password+"','')";
     
        connection.query(sql0, function (error, result, fields) {
          connection.release();
          if (error) {
            callback(error); 
          } else {  callback(null,result); }
         
        }); //end connection.query
      
      }); //end pool.getConnection
}

I would also like to clarify that i believe my function has all the right permissions (In the IAM role associated with the Lambdafunction), as if i test Gateway inserting a request body in format json, the query is inserted successfully in the DB. Here there is a screen of the response, together with the response Header : enter image description here

To specify that I Enabled CORS on my API and also my header response contains AllowControlallowOrigin : *.

Even though, when i tried to run my request through my homepage, i get this error enter image description here

If i try to insert mode : no-cors, in the JS, i get this error : POST net::ERR_ABORTED 415 (Unsupported Media Type.

So i found some thread where it was explained that with mode: no-cors my form-data was in text/char, instead of the application/json that the Gateway expected it to be. (The Gateway has mapping templates on integration request (Lambda type) of content type application/json)

I tried to change the mapping template body content type to text/char, and went from ---> to :

enter image description here

Now, as expected and anticipated from our first error where it was established that enabling mode: no-cors would result in an opaque response :

enter image description here

So i dont know what to do and what is causing me problems. I dont understand, to begin with, why it does prompt me with the error about CORS when i have Enabled CORS from Gateway and even the Response Header contains AllowControlAllowOrigin : *.

Also i tried to add in s3 bucket options error page being index.html, as someone suggested as solution to the opaque response, but i get enter image description here

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
redbite
  • 189
  • 1
  • 2
  • 10
  • The 415 error is the root problem; the CORS message is a side effect. – sideshowbarker May 12 '21 at 10:17
  • So the problem is how i pass the form data, so the JS script? – redbite May 12 '21 at 10:23
  • My guess is that you are using some kind of an API that has data encoded in a different way than JSON? If that is the case, then you need this: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html. – Marko E May 12 '21 at 10:32
  • @MarkoE How can i know what kind encoding does it need? If i test my gateway passing this kind of json request { "username": "mike", "email": "mike@gmail.com", "password": "grvdsc" } , i get "errorMessage": "Cannot read property 'username' of undefined", as for HTTP fetch. Yesterday worked fine at least with Gateway. – redbite May 12 '21 at 10:40
  • The encoding depends on the backend you are passing the data to. So, there are basically four types of backend integrations, two of which are considered "proxy" if the backend can work with JSON data. Other two require you to rewrite data using the VTL (in the link from my previous comment). Here's the explanation: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-integration-types.html. – Marko E May 12 '21 at 10:44
  • @MarkoE sorry but im kinda lost right now. Im trying to understand more but i get only more confused - if my gateway is connected to a lambda function i get only to choose between lambda and lambda proxy, right? Whats the difference? Actually, and at the time of writing this thread, my integration request is lambda, without proxy. – redbite May 12 '21 at 10:55
  • The backend is decided from Gateway, right? For each integration there is an encoding? so if i want just event.data1/data2 what should i do? Also, https://docs.aws.amazon.com/lambda/latest/dg/services-apigateway-tutorial.html i think this aws doc answers something, but im unsure what i should change. I dont know if i need to add a mapping template and for what values, then how to change the JS in the function to make it work with Gateway and so on – redbite May 12 '21 at 11:04
  • https://stackoverflow.com/questions/67520114/access-to-fetch-at-from-origin-has-been-blocked-by-cors-policy-no-access the problem was not the encoding or the data passthrough, even with a simple select its the same. – redbite May 13 '21 at 13:55

1 Answers1

0

In the end all i needed to do was : add Origin to API -> Enable Cors -> Allow Control Allow headers.

redbite
  • 189
  • 1
  • 2
  • 10