【问题标题】:Why does Express Middleware not fire when preceded by app.use(express.static(path.join(...)));为什么在 app.use(express.static(path.join(...))); 前面时 Express Middleware 不会触发
【发布时间】:2018-10-20 03:25:55
【问题描述】:

我正在尝试调试我非常简单的快速后端样板中的问题。我有一个通用中间件,我想在每个到达服务器的请求时触发它(本质上,我只是想设置一个 cookie。)

const express = require('express');
const path = require('path');
const uuidv4 = require('uuid/v4');
const cookieParser = require('cookie-parser')

const app = express();
app.use(cookieParser());

app.use(express.static(path.join(__dirname, 'client/build')));

app.use('/', (req, res, next) => {
    console.log(req.cookies)
    if (!req.cookies['audience_tracking_id']) {
        console.log('Processed Request - User Does Not Have Cookie.')
        const uniqueID = uuidv4();
        res.setHeader('Set-Cookie', [`audience_tracking_id=${uniqueID}`, `contentFocus=${randomProductName()}`]);
    }
    next();
});


app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname + '/client/build/index.html'))
});

app.use(function(err, req, res, next) {
    console.log(err)
    res.status(err.status || 500).send();
});

const port = process.env.PORT || 6000;

app.listen(port);

console.log(`Audience Service Host listening on ${port}`);

该应用程序包括一个托管在 Heroku 上的 React 前端,我通过 Express 在同一容器中提供静态构建文件。

问题是 - 我是否使用 Postman 在本地向 localhost:6000 中的此文件发送 GET 请求,或者我是否访问 Heroku 上的容器,console.log() 无法触发 - 可能还有其余的中间件。

但是,如果我将此行移到 cookie 中间件下方:

app.use(express.static(path.join(__dirname, 'client/build')));

或者,如果我只是将其注释掉,我的中间件就会触发并且 console.log() 会出现。这是一个简单的修复,但我不知道为什么会发生这种情况,有谁知道我在这段代码中做错了什么,导致中间件按原样失败?

【问题讨论】:

    标签: node.js express cookies middleware


    【解决方案1】:

    这是因为您的“静态文件”中间件会尝试将所有请求匹配到您的服务器:

    app.use(express.static(path.join(__dirname, 'client/build')))
    

    您的请求“GET localhost:6000/*”将在“cookie”中间件之前路由到“静态文件”中间件。如果“静态文件”中间件发现该文件存在,则响应将以该文件结束。如果不是,中间件的动作与选项有关(fallthrough),您可以在server-static's option 获得更多详细信息

    我建议为static file middlware设置根挂载路径:

    app.use("/dist", express.static(path.join(__dirname, 'client/build')))
    

    如果要检查所有请求中的 cookie,请使用以下格式:

    app.use((req, res, next) => {
        // Do something
    })
    

    【讨论】:

    • 您认为这是一个好的解决方案吗? :app.use((req, res, next) => { express.static(path.join(__dirname, 'client/build')); next(); });——在你的例子中,什么时候是向/dist发送请求的合适时间——我认为它应该在页面加载时自动进行,因为它包含 React 的 bundle.js 文件?
    • @Mikhail - 不,这行不通。调用express.static(...) 只是返回一个中间件函数。它实际上并没有执行任何操作。
    • @jfriend00 好的。我仍然对这个答案的性质有点困惑——“这是因为你的“静态文件”中间件会尝试将所有请求匹配到你的服务器”——即使所有请求都像我最初写的那样路由到静态中间件,为什么它会阻止后续中间件的执行?我之前在更大的 express 后端中使用过这种模式,并且它从未阻止我后续路由中的 console.logs 触发。
    • @Mikhail - 您可以就这个答案向menya 提问。我正在回复您的评论。
    • @Mikhail 当静态中间件匹配一些路由时,表示中间件通过路由找到存在的文件路径,文件将被流式传输到响应,当它完成时,响应将被关闭,所以其他中间件不管用。当静态中间件通过路由发现不存在的文件路径时,动作与选项(fallthrough)有关,您可以在serve-static 's doc找到更多详细信息
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-25
    • 1970-01-01
    • 2016-03-14
    • 2012-07-04
    • 2019-11-29
    • 2017-06-03
    相关资源
    最近更新 更多