捕获所有路由除了/ login

cli*_*uke 70 node.js express

我目前正在编写一个API,要求用户在每个请求的标头中传递身份验证令牌.现在我知道我可以创建一个catchall路线说

app.get('/*', function(req,res){

});
Run Code Online (Sandbox Code Playgroud)

但我想知道如何制作它以排除某些路线,如/login/

rob*_*lep 105

我不确定当用户访问时你想要发生什么,/login或者/你可以为那些创建单独的路由; 如果你在catch-all之前声明它们,它们会在处理传入的请求时获得第一个dib:

app.get('/login', function(req, res) {
  ...
});

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

app.get('*', function(req, res) {
  ...
});
Run Code Online (Sandbox Code Playgroud)

  • @SSHThis我认为使用最新版本的Express(v4),`app.use('*',...)`应该也可以.但在这种情况下,最好使用[`app.all('*',...)`](http://expressjs.com/en/4x/api.html#app.all). (3认同)
  • 这仅适用于“GET”,对吗?由于某种原因,我无法得到与“app.use”一起使用的答案(以包括其他方法)。 (2认同)

Leo*_*tny 43

您可以随时在要排除的路线之后放置全能路线(请参阅robertklep答案).

但有时你根本不想关心路线的顺序.在这种情况下,你仍然可以做你想要的:

app.get('*', function(req, res, next) {
  if (req.url === '/' || req.url === '/login') return next();
  ...
});
Run Code Online (Sandbox Code Playgroud)

  • @iLoveUnicorns thanx!你为什么不编辑我的帖子? (2认同)

小智 21

如果要在每个请求中验证凭据或真实性,应使用"快速路由"功能"全部",您可以像这样使用它:

app.all('/api/*', function(req, res, next){
    console.log('General Validations');
    next();
});
Run Code Online (Sandbox Code Playgroud)

你可以把它放在任何路由的东西之前.

请注意,在这种情况下,我使用"/ api/"作为路径,您可以使用"/ "它符合您的需要.

希望在这里帮助某人还为时不晚.


Jer*_*itz 10

制作全能路由处理程序的另一种方法是:

app.get('/login', function(req, res) {
  //... login page
});
app.get('/', function(req, res) {
  //...index page
});
app.get('/:pageCalled', function(req, res) {
  console.log('retrieving page: ' + req.params.pageCalled);
  //... mypage.html
});
Run Code Online (Sandbox Code Playgroud)

这与robertklep(已接受)的答案完全相同,但它为您提供了有关用户实际请求的更多信息.您现在有一个slug req.params.pageCalled来表示正在请求的任何页面,如果您有几个不同的页面,可以将用户定向到相应的页面.

一个得到用这种方法注意的(thx @agmin),/:pageCalled只会抓住一条路线/,所以你不会得到/route/1,等等.使用/:pageCalled/:subPageCalled更多的页面(thx @softcode)

  • 这种方法有一个巨大的问题,`/:pageCalled`只会捕获一个`/`的路由,所以你不会得到`/ route/1`等. (14认同)

Cir*_*四事件 6

负向前瞻正则表达式

也许这有时会派上用场:

const app = require('express')()
app.get(/^\/(?!login\/?$)/, (req, res) => { res.send('general') })
app.get('*',                (req, res) => { res.send('special') })
app.listen(3000)
Run Code Online (Sandbox Code Playgroud)

有了这个,你会得到:

/           general
/asdf       general
/login      special
/login/     special
/login/asdf general
/loginasdf  general
Run Code Online (Sandbox Code Playgroud)

或者如果您也想/login/asdf成为special

app.get(/^\/(?!login($|\/.*))/, (req, res) => { res.send('general') })
Run Code Online (Sandbox Code Playgroud)

特别是,当我在这里 Google 搜索时,我正在考虑在执行 SPA API 的同一服务器上提供静态前端文件的情况:

const apiPath = '/api';
const buildDir = path.join(__dirname, 'frontend', 'build');

// Serve static files like /index.html, /main.css and /main.js
app.use(express.static(buildDir));
// For every other path not under /api/*, serve /index.html
app.get(new RegExp('^(?!' + config.apiPath + '(/|$))'), function (req, res) {
  res.sendFile(path.join(buildDir, 'index.html'));
});

// Setup some actions that don't need to be done for the static files like auth.
// The negative lookahead above allows those to be skipped.
// ...

// And now attach all the /api/* paths which were skipped above.
app.get(apiPath, function (req, res) { res.send('base'); });
app.get(apiPath, function (req, res) { res.send('users'); });

// And now a 404 catch all.
app.use(function (req, res, next) {
  res.status(404).send('error: 404 Not Found ' + req.path)
})

// And now for any exception.
app.use(function(err, req, res, next) {
  console.error(err.stack)
  res.status(500).send('error: 500 Internal Server Error')
});

app.listen(3000)
Run Code Online (Sandbox Code Playgroud)

在express@4.17.1、Node.js v14.17.0 上测试。