【问题标题】:Express middleware calls multiple timesExpress 中间件调用多次
【发布时间】:2019-02-09 21:13:23
【问题描述】:

我查看了与此主题相关的其他帖子,但在我的代码中找不到问题。

const myMiddleware = (fn) => {
    return (req, res, next) => {
        var fullUrl = req.protocol + '://' + req.get('host') + req.url;
        console.log(fullUrl)
        next()
    }
}

const app = express()

app.use('/dist', express.static(__dirname + '/client/dist'))
app.use('/static', express.static(__dirname + '/client/static'))

app.use(bodyParser.urlencoded({ extended: false }))
app.use(cookieParserMiddleware())
app.use(passport.initialize())

const server = https.createServer(options, app)

app.get('/', myMiddleware((req, res) => {
    res.sendFile(__dirname + '/client/dist/index.html')
}))

app.all('*', (req, res) => {
    res.redirect('/')
})

server.listen(8080, function listening() {
    console.log('Listening on %d', server.address().port)
})

没有myMiddleware 上的'/' 路径,一切都按预期工作。将myMiddleware 附加为app.get('/', myMiddleware((req, res) => {,然后多次调用myMiddleware 而没有调用res.sendFile(__dirname + '/client/dist/index.html')


编辑:下面的错误已通过 jfriend00 的解决方案修复。被多次调用的中间件仍然存在。原因是图标和其他一些资产没有被app.use('/static', express.static(__dirname + '/client/static')) 行捕获。修复路径也解决了第一个错误

除此之外,我尝试删除下面的部分,但该应用程序根本无法运行。我的猜测是这里有 2 个错误。

app.all('*', (req, res) => {
    res.redirect('/')
})

我发布了一张图片,说明删除 app.all('*'..) 后的外观

【问题讨论】:

  • 您的中间件编写不正确。我不知道你想用它做什么,但你传递给它的回调从未使用过。它所做的只是调用next()
  • @jfriend00 通常里面会写代码,但为了找出问题所在,我已经对其进行了简化以进行测试。您可以假设它有 console.log() 或内部的一些其他逻辑
  • 你知道app.get('/', myMiddleware((req, res) => {...}); 从不做任何事吗?它所做的只是调用next()。这就是我的观点。我不知道您打算做什么,但它在您的代码示例中没有任何用途。我无法说出您的问题到底是什么,所以我不知道这是否与问题有关。因此,您的所有代码所做的只是重定向到 /,然后重定向到 /,再重定向到 /,依此类推。它从不做任何其他事情,而是无限循环,直到浏览器可能检测到太多重定向。
  • 想象它做了一些事情。为了您的利益,我编辑了代码以打印 url。没有中间件,就没有重定向循环,应用程序也能正常工作。 any 中间件有重定向循环。
  • 你需要一个除了重定向之外做一些事情的路由。你一个都不显示。因此,您的服务器所做的只是一遍又一遍地重定向。如果你不能得到那个或向我们展示更多你的真实代码,那么我会继续。

标签: javascript node.js express middleware express-router


【解决方案1】:

我在这里做个猜测。

改变这个:

app.get('/', myMiddleware((req, res) => {
    res.sendFile(__dirname + '/client/dist/index.html')
}));

到这里:

app.get('/', myMiddleware(), (req, res) => {
    res.sendFile(__dirname + '/client/dist/index.html')
}));

这样您的res.sendFile()myMiddleware 调用next() 之后实际上会被调用。


然后,删除 fn 参数,这样你就有了(不会改变执行,但会删除误导性和未使用的参数):

const myMiddleware = () => {
    return (req, res, next) => {
        var fullUrl = req.protocol + '://' + req.get('host') + req.url;
        console.log(fullUrl)
        next()
    }
}

【讨论】:

  • 我提到有两个错误。 (1) 多次调用中间件 (2) 删除app.all('*', (req, res) => { 会导致错误。应用您的更改后,我们已经修复了此错误 #2,但是,调用 localhost:8080 将调用 myMiddleware 3 次
  • @Thellimist - 这并不奇怪。对您的服务器的一次调用将用于 favicon。您的 HTML 页面中是否有任何 <img> <script> 标记或其他资源引用来对您的服务器进行其他调用。您正在将 URL 记录在中间件中。您可以看到请求的内容,对吗?
  • 我有 static/css/lobby.cssstatic/css/style.css 和 favicon。他们打电话是正常的还是有更好的方法?
  • @Thellimist - 这就是浏览器获取这些文件的方式。它为每个请求返回到您的服务器。这就是网页的工作原理。
  • 他们正在调用static/ 路径,所以我假设express.static 中间件会捕获该请求,而不是将其一直传递给myMiddleware。我错过了什么吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-04
  • 2016-04-08
  • 2013-07-04
  • 2019-11-03
相关资源
最近更新 更多