badera
badera

Reputation: 1555

node.js: serve static web, match request url //*/web/ to file system /web/

I use node.js in a simple way to serve a static web.

...
app.use(express.static('./build'));
http.createServer(app).listen(port, ipaddress);
...

This serves the files 1:1 (with index.html as default resource), e.g.

//server/a.html -> ./build/a.html
//server/bbb/x.html -> ./build/bbb/x.html
//server/ccc/ -> ./build/index.html

But now, I need to be able to remove 'one level' of the request url, but it shall serve still the same web, e.g.

//server/aaaa/a.html -> ./build/a.html
//server/bbbb/a.html -> ./build/a.html
//server/xxxx/bbb/x.html -> ./build/bbb/x.html
//server/yyy/ccc/ -> ./build/ccc/index.html

So I need a wildcard matching in the request url. I tried this:

app.use('/\*', express.static('./build'));
http.createServer(app).listen(port, ipaddress);

But with no luck. No more page is accessible. What is wrong?

[Edited to show that the server should serve index.html as default resource]

Upvotes: 0

Views: 421

Answers (2)

badera
badera

Reputation: 1555

My final solution is:

// serve all files from ./web directory regardless of first element in url
app.get('/:leveltoremove/*', function(req, res) {
  var path = req.params[0] ? req.params[0] : 'index.html';
  res.sendfile(path, {root: './web'});
});

http.createServer(app).listen(port, ipaddress);

Upvotes: 1

mscdex
mscdex

Reputation: 106736

Depending on your application, you might put express.static() on separate Router instances that are mounted on your app. For example:

var routerA = new express.Router();
// You could also reuse the same static file handler since they
// are all using the same root path
routerA.use(express.static('./build'));
// and other `routerA` route handlers ...

var routerB = new express.Router();
routerB.use(express.static('./build'));
// and other `routerB` route handlers ...

// etc.

However if you don't have your application broken up like this already, you could also specify multiple routes like:

app.use(['aaaa', 'bbbb', 'xxxx'], express.static('./build'));

Or if nothing else, you could just use a custom middleware, calling the static file handler manually (although this is kind of a hack, as it was what separate, mounted Routers were designed to help solve):

var staticHandler = express.static('./build');
app.use(function(req, res, next) {
  var m = /^\/[^/]+(\/.+)$/.exec(req.url);
  if (m) {
    // Temporarily override the `req.url` so that the path
    // concatenation will happen correctly
    var oldUrl = req.url;
    req.url = m[1];
    staticHandler(req, res, function(err) {
      // Reverting the to the original `req.url` allows
      // route handlers to match the request if a file
      // was not found
      req.url = oldUrl;
      next(err);
    });
  } else
    next();
});

app.get('/aaa/foo', function(req, res) {
  res.end('hello from /aaa/foo!');
});

Upvotes: 1

Related Questions