Home > other >  How does a pre-flight request receive headers without having a response?
How does a pre-flight request receive headers without having a response?

Time:12-24

I've been reading about CORS and pre-flight requests, and have understood that basically it is a type of an OPTIONS request that is sent before making the actual request and if the server permits it then the actual request is sent again. But what's confusing me the most is that how is the browser able to receive response headers without receiving the actual response from the server?? Are headers sent regardless if a response has been sent or not?? Like in the below nodejs code snippet you could see that I've created a middleware which receives the OPTIONS request and responds with the headers required for the actual request to be sent. And once it is validated on the same login route browser sends the actual request. But you must've noticed that I'm not sending a response from the handler of the OPTIONS middleware function I'm only sending the headers. Then how is this all still working out?? how are the headers sent to the browser without a response?

app.options("/login", (req, resp, next) => {
  resp.header("Access-Control-Allow-Origin", "http://127.0.0.1:5500");
  resp.header("Access-Control-Allow-Methods", "GET, POST, PUT");
  resp.header("Access-Control-Allow-Headers", "Content-type");
  next();
});

app.post("/login", (req, resp) => {
  resp.header("Access-Control-Allow-Origin", "http://127.0.0.1:5500");
  resp.header("Access-Control-Allow-Methods", "GET, POST, PUT");
  resp.header("Access-Control-Allow-Headers", "Content-type");
  resp.json({
    msg:"Sucess"
  });
});

CodePudding user response:

To answer this question you need to take a look at the express source code. In router\index.js (which will be eventually executed after you called next() from your handler), you'll find the following code:

  // for options requests, respond with a default if nothing else responds
  if (req.method === 'OPTIONS') {
    done = wrap(done, function(old, err) {
      if (err || options.length === 0) return old(err);
      sendOptionsResponse(res, options, old);
    });
  }

In your case the if condition is false since you did not respond in your handler resulting in a call to sendOptionsResponse, which is defined as follows:

// send an OPTIONS response
function sendOptionsResponse(res, options, next) {
  try {
    var body = options.join(',');
    res.set('Allow', body);
    res.send(body);
  } catch (err) {
    next(err);
  }
}

And that's why a response is actually sent even though you did not explicitly send it from your handler.

Btw: you might wanna take a look at the cors-package which greatly helps to facilitate the cors-setup.

  • Related