简体   繁体   English

express.static() 的 Express 中间件未正确路由并抛出 next() 不是 function

[英]Express middleware for express.static() not routing correctly and throwing next() is not a function

Despite this running correctly on my local machine while I was writing and testing it, it seems to fail when deployed out to our UAT environment using Docker.尽管在我编写和测试它时它在我的本地机器上正常运行,但在使用 Docker 部署到我们的 UAT 环境时似乎失败了。 I can't seem to track down why it's giving me the following:我似乎无法追查为什么它给了我以下信息:

next() is not a function

I also seem to be having a routing issue (again only when it's deployed) where even if it when the route is /media/public it seems to still hit the /media route.我似乎也遇到了路由问题(再次仅在部署时),即使当路由是 /media/public 时,它似乎仍然会命中 /media 路由。

dependencies依赖关系

"dotenv": "^8.2.0",
"express": "^4.17.1",
"jsonwebtoken": "^8.5.1"

server.js服务器.js

require('dotenv').config();
const express = require('express');
const { join } = require('path');
const { fileExists, isAuthenticated } = require('./helpers/utils');
const { PORT, ROOT_SHARE } = process.env;
const app = express();

global.__basedir = __dirname

app.use('/robots.txt', function (_req, res) {
    res.type('text/plain');
    res.send('User-agent: *\nDisallow:/');
});

app.use('/media/public', [fileExists, express.static(join(__dirname, ROOT_SHARE, '/public'))]);
app.use('/media', [isAuthenticated, express.static(join(__dirname, ROOT_SHARE))]);

app.listen(PORT, () => console.info(`[File Server] : running on ${PORT}`));

utils.js实用程序.js

const { existsSync } = require('fs');
const { verify } = require('jsonwebtoken');
const { join } = require('path');
const { ACCESS_SECRET, NODE_ENV  } = process.env;

const fileExists = async (req, res, next) => {
    let mediaFile = (NODE_ENV === 'local') ? join(__basedir, req.baseUrl, req.path).replace('\\src','') : req.originalUrl;
    console.log(mediaFile);
    if (!existsSync(mediaFile)) {
        console.log('NOT FOUND')
        return res.status(404).send('NOT FOUND');
    }

    return next();
}

const isAuthenticated = async (req, res, next) => {
    const accessToken = valueOrNull((req.cookies && req.cookies['x-access-token']) || (req.headers && req.headers['x-access-token']));
    
    if (!accessToken) {
        console.log('accessToken not found')
        return res.status(401).send('UNAUTHORIZED');
    }

    try {
        fileExists(req);
        const { user } = verify(accessToken, ACCESS_SECRET);

        if (user) {
            console.log('VALID USER');
        }
    } catch (err) {
        console.log(err)
        return res.status(401).send('UNAUTHORIZED');
    }

    return next();
};

const valueOrNull = (value) => {
    return (typeof value == 'undefined' || value === null || value === '') ? undefined : value;
}

module.exports = {
    fileExists,
    isAuthenticated
}

.env .env

ROOT_SHARE=../media

Dockerfile Dockerfile

FROM node:latest

RUN mkdir -p /media

WORKDIR /app

COPY package.json .
COPY package-lock.json .

RUN npm install && npm cache clean --force --loglevel=error

RUN npm install -g pm2

COPY src /app/src

EXPOSE 3000

ENTRYPOINT ["node", "src/server.js"]

exact error精确误差next() 不是函数

Any help would be greatly appreciated任何帮助将不胜感激

Your fileExists is being used both as a middleware and as a function called in isAuthenticated — in isAuthenticated it's not being passed res or next .您的fileExists既被用作中间件,又被用作在isAuthenticated中调用的 function - 在isAuthenticated中,它没有被传递resnext If you do pass it there, you may end up having other issues, since both functions call res.status(status).send() .如果你确实将它传递到那里,你最终可能会遇到其他问题,因为这两个函数都调用res.status(status).send() You also have some async keywords on those functions when they're not await ing anything — that's not breaking anything, it's just a waste of a few characters:).当这些函数没有await任何东西时,您还可以在这些函数上使用一些async关键字——这并没有破坏任何东西,只是浪费了几个字符:)。

You call:你打电话:

fileExists(req);

but your implementation of fileExists() expects you to pass it (res, res, next) and you are not passing that.但是您的fileExists()实现希望您通过它(res, res, next)并且您没有通过它。 Thus, you get the error next() is not a function when fileExists() tries to call next() .因此,当fileExists()尝试调用next()时,您会收到错误next() is not a function

It's not clear to me exactly what you're trying to do, but perhaps you can change to this where you pass (req, res, callback) to fileExists() and then you continue your processing in that callback.我不清楚您到底要做什么,但也许您可以更改为将(req, res, callback)传递给fileExists()的位置,然后在该回调中继续处理。 That's how you manually call middleware yourself which it appears you are trying to do:这就是您自己手动调用中间件的方式,您似乎正在尝试这样做:

const isAuthenticated = (req, res, next) => {
    const accessToken = valueOrNull((req.cookies && req.cookies['x-access-token']) || (req.headers && req.headers['x-access-token']));
    
    if (!accessToken) {
        console.log('accessToken not found')
        return res.status(401).send('UNAUTHORIZED');
    }

    try {
        fileExists(req, res, () => {
            const { user } = verify(accessToken, ACCESS_SECRET);

            if (user) {
                console.log('VALID USER');
            }
            return next();

        });
    } catch (err) {
        console.log(err)
        return res.status(401).send('UNAUTHORIZED');
    }

};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM