【问题标题】:How to avoid the ambiguity of routes in Express.js如何避免 Express.js 中路由的歧义
【发布时间】:2017-04-11 09:02:56
【问题描述】:

我有三个文件server.js, views.jsaccess.js

server.js我已经把所有dependencies和一些routes之类的都放了

app.post('/services/getallversions', (req, res) => {
... 
// code to handle the req and send response
})

views.js 我有如下代码,

module.exports = function(app, db, bodyParser, rules, constants, query) {

app.post('/services/user/:user/:type', (req, res) => {
// user can be 'abcd'
// type can be addview, deleteview etc.

...
// do processing for the req and send res
})


}

access.js 我有类似的代码,

module.exports = function(app, db, bodyParser, rules, constants, query) {

app.post('/services/user/:user/:type', (req, res) => {
// user can be 'abcd'
// type can be addaccess, removeaccess etc.

...
// do processing for the req and send res
})


}

server.js 文件中,我需要access.js and views.js 以下方式,

var access = require('./access')(app, db, bodyParser, rules, constants, query)
var views = require('./views')(app, db, bodyParser, rules, constants, query)

当我尝试使用/services/user/abcd/addaccess POST 时,我的views.js 文件代码被执行。 constants, query, rules 是其他 .js 文件,已在 server.js 中使用 require('./filename')

我了解此歧义是由于相同的 URL 结构造成的。我正在使用 Express 4 和 Node JS 6。我想将 access.jsviews.js 的代码与 server.js 分开,并将它们放在单独的文件中,并以上述方式要求它们。 views.jsaccess.js 是我创建的。它们不是任何 Javascript 框架或类似的东西。

view.js我也试过下面的代码

var router = require('express').Router()

router.post('/services/user/:user/:type', (req,res)=>{})

但同样的问题也存在。有什么方法可以实现吗?

【问题讨论】:

  • 我很难理解你到底在问什么。服务器究竟应该如何知道是运行views.js 还是access.js 代码?网址完全相同相同。你知道这个问题,但如果不使用不同的 URL,就不可能解决,简单明了。当您包含views.js 另一个文件之后,app.post() 调用简单地覆盖access.js 中的那个。

标签: javascript node.js express


【解决方案1】:

我建议您在 Express 中使用“miniApp”概念,其中每个“miniApp”都使用名称空间进行区分。

例如: 主应用:

所有带有'/views/...'前缀的路由都将转到viewsCtrl。这个中间件应该出现在你的默认/主应用路由之前:

 var viewsCtrl = require('./views');
 app.use('/views', viewsCtrl);

views.js 内部:

var router = require('express').Router();
// complete route /views/services/user/:user/:type
router.get('/services/user/:user/:type', function(req, res){...});
module.exports = router;

access.js 也是如此。

【讨论】:

  • @Aman Gupta:能给我viewsCtrl代码吗?我想知道如何组织代码??
  • 第二部分是viewsCtrl,我刚刚在mainApp中需要重命名。
【解决方案2】:

路由是相同的,express 永远无法判断该调用哪一个。订单不是这里的问题;正如 Chris G 在评论中所说,第二次调用 app.post(...) 将覆盖第一次(将 URL 视为哈希集中的键)。

你已经知道url的格式是/addview/removaccess等,所以你可以把这些知识放在路由中间件中:

// access.js
app.post('/services/user/:user/access/:type', (req, res) => {
  // ... type is now only add, remove, etc...
})

// view.js
app.post('/services/user/:user/view/:type', (req, res) => {
  // ...
})

甚至(我认为):

// access.js
app.post('/services/user/:user/:type((access)$)/', (req, res) => {
  // ... will match addaccess, removeaccess and so on
  // but I'm not entirely sure ...
})

参考这里:

https://expressjs.com/en/guide/routing.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-20
    • 1970-01-01
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多