Expressjs路由器基于Content-Type头

对于路由,我希望我的中间件将请求传递到/ html文件夹中定义的路由到服务器HTML(ejs),如果Content-Type是application / json,则使用/ api文件夹中定义的路由。

但是我不想在每条路线上都定义这一点。 所以我不是在寻找定义一些req.api属性的中间件,我可以在每个路由中检查它

app.get('/', function(req, res) { if(req.api_call) { // serve api } else { // serve html } }); 

但是我想要这样的东西:

 // HTML folder app.get('/', function(req, res) { res.send('hi'); }); // API folder app.get('/', function(req, res) { res.json({message: 'hi'}); }); 

这是可能的,如果是这样,我该怎么做?

我希望能够像这样工作:

 app.use(checkApiCall, apiRouter); app.use(checkHTMLCall, htmlRouter); 

您可以将其作为Express链中的第一个中间件插入,中间件处理程序检查请求types,然后通过向其中添加前缀path将req.url修改为伪URL。 然后这个修改会强制这个请求去只有一个特定的路由器(一个路由器设置来处理这个特定的URL前缀)。 我已经使用以下代码在Express中validation了这一点:

 var express = require('express'); var app = express(); app.listen(80); var routerAPI = express.Router(); var routerHTML = express.Router(); app.use(function(req, res, next) { // check for some condition related to incoming request type and // decide how to modify the URL into a pseudo-URL that your routers // will handle if (checkAPICall(req)) { req.url = "/api" + req.url; } else if (checkHTMLCall(req)) { req.url = "/html" + req.url; } next(); }); app.use("/api", routerAPI); app.use("/html", routerHTML); // this router gets hit if checkAPICall() added `/api` to the front // of the path routerAPI.get("/", function(req, res) { res.json({status: "ok"}); }); // this router gets hit if checkHTMLCall() added `/api` to the front // of the path routerHTML.get("/", function(req, res) { res.end("status ok"); }); 

注意:我没有填写checkAPICall()checkHTMLCall()的代码,因为你没有完全明确你想如何工作。 我在我自己的testing服务器上嘲笑他们,看看这个概念的工作原理。 我假设你可以为这些函数提供适当的代码,或者replace你自己的if语句。

事先答复

我刚刚证实你可以在Express中间件中更改req.url ,所以如果你有一些修改了req.url中间件,它会影响到这个请求的路由。

 // middleware that modifies req.url into a pseudo-URL based on // the incoming request type so express routing for the pseudo-URLs // can be used to distinguish requests made to the same path // but with a different request type app.use(function(req, res, next) { // check for some condition related to incoming request type and // decide how to modify the URL into a pseudo-URL that your routers // will handle if (checkAPICall(req)) { req.url = "/api" + req.url; } else if (checkHTMLCall(req)) { req.url = "/html" + req.url; } next(); }); // this will get requests sent to "/" with our request type that checkAPICall() looks for app.get("/api/", function(req, res) { res.json({status: "ok"}); }); // this will get requests sent to "/" with our request type that checkHTMLCall() looks for app.get("/html/", function(req, res) { res.json({status: "ok"}); }); 

较老的答案

我能够成功地将请求callback放在这样的快递前面,并且看到它成功修改了传入的URL,从而影响了快速路由,如下所示:

 var express = require('express'); var app = express(); var http = require('http'); var server = http.createServer(function(req, res) { // test modifying the URL before Express sees it // this could be extended to examine the request type and modify the URL accordingly req.url = "/api" + req.url; return app.apply(this, arguments); }); server.listen(80); app.get("/api/", function(req, res) { res.json({status: "ok"}); }); app.get("/html/", function(req, res) { res.end("status ok"); }); 

这个例子(我testing过)只是在URL的前面添加“/ api”,但你可以自己检查传入的请求types,然后根据需要修改URL。 我还没有探讨这是否可以完全在Express内完成。

在这个例子中,当我请求“/”时,我被给了JSON。