如何针对不接受 JSON 的请求跳过快速子应用

How to skip an express sub app for requests that don't accept JSON

我有两个 Express 子应用设置。一个将服务于后端 API,另一个将服务于我的 React 单页应用程序。然后这两个应用程序都安装在主应用程序中。如果传入请求接受 JSON.

,我只想将请求发送到 apiServer 子应用程序

这是我目前的情况。

const express = require( 'express');

// two express sub apps
const reactServer = require('./reactServer');
const apiServer = require('./apiServer')

const app = express();

// middelware to check for json
const onlyJSON = (req, res, next)=>{
  if(req.headers.accept.indexOf('json') === -1){
    next('route') // this doesn't appear to work
  }else{
   next()
  }
}

app.use('/api', onlyJSON, apiServer);
app.use('/', reactServer);
app.listen(3000);

这行不通。来自浏览器的请求仍然由 apiServer 处理。这个想法是它们应该流向 reactServer。这是可以做到的吗?

问得好。似乎真的没有办法做你想内置表达的东西。然而,在搜索报告的问题时,结果发现至少有一个人 also wants that feature and actually wrote a pitstop module 看起来符合您的要求:

const pitstop = require('pitstop');

const apiIfJson = pitstop()
  .condition((req, res, next) => next(req.headers.accept.indexOf('json') !== -1))
  .use(apiServer);

app
  .use('/api', apiIfJson)
  .use('/', reactServer)
  .listen(3000);

如果你使用 app.all() 而不是 app.use(),你可以让它工作。

快速示例:

let apiRouter   = express.Router();
let reactRouter = express.Router();

const onlyJSON = (req, res, next)=>{
  if(req.headers.accept.indexOf('json') === -1){
    next('route');
  } else{
   next()
  }
}

apiRouter  .use((req, res) => res.send('api'));
reactRouter.use((req, res) => res.send('react'));

app.all('/api*', onlyJSON, apiRouter);
app.all('*',    reactRouter);

我想是因为app.use()不是路由,所以next('route')不行。