0

I'm trying to send a POST request using Javascript fetch with application/json as the content-type and am having issues. When I do the request in Postman, it works fine. When I try to do it via Javascript fetch, I get an error and on the GCF logging side, when I try to log console.log(req.body), nothing is registered.

I am able to successfully get the request body to show up and register when I change the request content-type to text/plain and then parse the JSON after the fact in my cloud function, but I'd like to remove this extra step if possible (and also figure out why this isn't working).

Here is the client-side fetch request (essentially pasted from Postman) where the body doesn't get passed for some reason, I've tried various combinations of removing quotes from the property names and also removing the stringify:

    var myHeaders = new Headers();
    myHeaders.append("Content-Type", "application/json");

    var raw = JSON.stringify({"key1":"value1","key2":"value2"});

    var requestOptions = {
      method: 'post',
      headers: myHeaders,
      body: raw,
      redirect: 'follow'
    };

    fetch("mycloudfunctionsurl", requestOptions)
      .then(response => response.text())
      .then(result => console.log(result))
      .catch(error => console.log('error', error));

Here is my Node.JS runtime 10 Cloud Function code:

exports.helloHttp = async ( req, res ) => {
    res.set('Access-Control-Allow-Origin', '*');

    console.log(req.body); // <-- Shows up with Postman but not above code, unless I change to text/plain

    var key1 = req.body.key1;
    console.log('key1 is ' + key1);

    // other functions to process the response body
  
};
policenauts
  • 512
  • 6
  • 18
  • Are you also trying to satisfy CORS requirements here? – Doug Stevenson Aug 08 '20 at 20:08
  • Hi @DougStevenson the error I'm getting on the client side is a CORS error, but I've received those errors before from http requests as a generic error, and also in this case a POST request with a different content type is working so I didn't think it was CORS related. Is this actually a CORS issue related to the content type being JSON? If so, how do I resolve it? To answer your question, the request is coming from a different origin. Thank you. – policenauts Aug 08 '20 at 22:00
  • I found my answer: https://stackoverflow.com/questions/38998684/cant-send-a-post-request-when-the-content-type-is-set-to-application-json – policenauts Aug 08 '20 at 23:55

1 Answers1

0

This is probably a CORS issue. When making a cross-site request, there is an initial pre-flight request made to the function that is not request body that you posted. The fact that you see no body in the function is likely to do the fact that it's receiving this pre-flight request ahead of the intended post. Since the response isn't authorizing the cross-site request, your followup POST is never making it.

I suggest looking at this other question and use the nodejs cors module to implement it properly.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • Thanks Doug, I'll try this. But why does changing the content-type of the post body to text/plain make it work without needing to enable the cors middleware? And how come this isn't documented in the (non Firebase) Cloud Functions? https://cloud.google.com/functions/docs/writing/http#functions_http_cors-nodejs – policenauts Aug 08 '20 at 22:27
  • No idea. I'm taking a guess here based on how I understand cors to work. – Doug Stevenson Aug 08 '20 at 23:00
  • Thanks Doug, I think I found my answer: https://stackoverflow.com/questions/38998684/cant-send-a-post-request-when-the-content-type-is-set-to-application-json – policenauts Aug 08 '20 at 23:55