Home > Software engineering >  why app.use() in js express might not work?
why app.use() in js express might not work?

Time:11-30

I'm trying to handle CORS issue and add necessary strings to respond's headers: `

var express = require('express');
const app = express();
var router = express.Router();

router.options('/*', function(req, res, next){
  app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
  });
  res.sendStatus(200);
  console.log(res.getHeaders());
});

` But it doesn't work - console.log(res.getHeaders()) shows standard header:

[Object: null prototype] {
  'x-powered-by': 'Express',
  'content-type': 'text/plain; charset=utf-8',
  'content-length': '2',
  etag: 'W/"2-nOO9QiTIwXgNtWtBJezz8kv3SLc"'
}

What might prevent triggering this function?

In despair, I tried this construction: `

router.options('/*', function(req, res, next){
  const respond = async function() {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  }
  respond()
  res.sendStatus(200);
  console.log(res.getHeaders());
});

` And it does work:

[Object: null prototype] {
  'x-powered-by': 'Express',
  'access-control-allow-origin': '*',
  'access-control-allow-headers': 'Origin, X-Requested-With, Content-Type, Accept',
  'content-type': 'text/plain; charset=utf-8',
  'content-length': '2',
  etag: 'W/"2-nOO9QiTIwXgNtWtBJezz8kv3SLc"'
}
OPTIONS /email 200 4.345 ms - 2

What I'm doing wrong and where to look for the error

CodePudding user response:

The app.use statement with the CORS handling middleware must come before the other middlewares. And such statements must all be on the top level, not nested in one another:

const app = express();
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});
var router = express.Router();
router.options('/*', function(req, res, next){
  res.sendStatus(200);
  console.log(res.getHeaders());
});

Your nested app.use statement is executed only when an incoming request is handled by the router. But by then it is too late, because this will effectively register the CORS handling middleware last.

Your desparate solution works because it does not involve registering a new middleware.

As an alternative to homegrown CORS handlers, you may want to consider the cors package.

CodePudding user response:

I found that I can put res.header(...) right into the body of the router, without using app.use():

router.options('/*', function(req, res, next){
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    res.sendStatus(200);
    console.log(res.getHeaders());
});

and it works. Probably, the solution was always on the surface, but I spent almost a day to get this :)

  • Related