Home > OS >  Firebase HTTP Function triggered twice when POST request sent with headers
Firebase HTTP Function triggered twice when POST request sent with headers

Time:02-15

I deployed a firebase HTTP cloud function and am experiencing this (unexpected) behavior:

  • when I call the function (using POST) from a browser environment with fetch(), the function gets triggered twice, one time without any data sent in the body, and another time as I would expect it. In the frontend (chrome network tab) I can only see 1 request, the successfull one.
  • this does only happen with POST requests
  • this does only happen when the request is sending headers

Is this normal behavior that I dont understand or a potential bug?

my minimal cloud function

exports.run = functions.https.onRequest(async (req, res) => {
  // ALLOW CORS FOR POST REQUEST:
  // => https://stackoverflow.com/a/38259193
  res.set('Access-Control-Allow-Origin', '*');
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");

  return res.status(200).send({
    status: "ok",
    body: req.body,
    query: req.query,
  }).end();
});

calling from frontend

// example data (not a real one)
const url = "https://us-central1-myproject.cloudfunctions.net/test";
const postData = { x: 1, y: 2 };

// GET request => ✅ works as expected
fetch(url);

// POST request without headers => ✅ works as expected
fetch(url, {
  method: 'POST',
  body: JSON.stringify(postData),
});

// POST request with headers => ❌ 2 requests get triggered
fetch(url,  {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(postData),
});

CodePudding user response:

This behavior is happening because of the CORS preflight request:

A CORS preflight request is a CORS request that checks to see if the CORS protocol is understood and a server is aware using specific methods and headers. ... A preflight request is automatically issued by a browser, and in normal cases, front-end developers don't need to craft such requests themselves. It appears when a request is qualified as "to be preflighted" and omitted for simple requests.

As pointed in this other question:

As long as you’re adding a Content-Type': 'application/json' header to the request, the browser is going to automatically on its own do a CORS preflight OPTIONS request before trying the request from your code.

Therefore, this is a normal behavior and is not a problem of Cloud Functions for Firebase.

In order to not have the two requests, you can change the header request as suggested by this answer:

// example data (not a real one)
const url = "https://us-central1-myproject.cloudfunctions.net/test";
const postData = { x: 1, y: 2 };
    
// POST request with different header  => ✅ only one request is triggered
fetch(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: JSON.stringify(postData),
}).then(data => console.log(data));
  • Related