express icon indicating copy to clipboard operation
express copied to clipboard

force leading slash with middleware

Open Et7f3 opened this issue 2 years ago • 2 comments

I come after this: https://github.com/expressjs/express/commit/ef497fdae413f85362d319436cf113edf6320677#diff-f7dc29b565d7b8578bbabcd36d010c1eb95527acd5f1395bf3e1a2d4506360c5R425-R437

This seems to be the intended default behavior but in my case I really need namespace. If I let user query /user instead of /user/ path of css are wrong. I know of https://developer.mozilla.org/fr/docs/Web/HTML/Element/base or maybe other way to specify in html. I don't know specific header in http to update this.

I serve content I have no control over (so I can modify on the fly but would like to avoid overhead). I can't imagine a way to use a redirection ? because / in the router match no /. I have enabled strict routing (tried both syntax just in case I did a typo: app.set('strict routing', true); and app.enable('strict routing');)

Et7f3 avatar Nov 27 '23 20:11 Et7f3

Hello, I would love to better help, but hard to give good direction without a lot to go on. Based on what you said so far, I can confirm that app.use is meant to be sloppy on the trailing slash. But the route methods like app.all are not. I am curious if app.all('/user/*', ...) is a better fit for your use case.

dougwilson avatar Nov 27 '23 20:11 dougwilson

Sorry for long delay (It seemed the answers were blocked).

What I tried:

const app = express();
const router = express.Router();

router.get('/users/info', function(req, res) {
  res.write('info');
  res.end();
});

router.get('lists', function(req, res) {
  res.end('lists');
});

app.get('/home.html', function(req, res) {
  res.send('/home.html');
});

app.all('/users/*', function (req, res, next) {
  res.write('/users/');
  next();
  res.end();
}, router);


app.listen(3000);

It worked. You suggested to use app.all in combination to '/*' at the end of path. Only the last part is useful and works for app.get this leads me to use a proper regex and /^\/users\/$/allowed me to force a leading slash.

When testing router/app.all I expected it avoid to repeat base path but I didn't managed to avoid repetition of '/users/'when defining route:

$ set -x; for p in /users/ /users/info /users/lists; do curl http://localhost:3000"$p" -w "%{stdout}\n"; done; set +x
+ for p in /users/ /users/info /users/lists
+ curl http://localhost:3000/users/ -w '%{stdout}\n'
/users/
+ for p in /users/ /users/info /users/lists
+ curl http://localhost:3000/users/info -w '%{stdout}\n'
/users/info
+ for p in /users/ /users/info /users/lists
+ curl http://localhost:3000/users/lists -w '%{stdout}\n'
/users/
+ set +x

I expected to have /users/lists but it can't find it. So they serve to define middleware only on a sub-list of paths ?

Et7f3 avatar Jan 15 '24 08:01 Et7f3