【问题标题】:Express middleware for express.static() not routing correctly and throwing next() is not a functionexpress.static() 的 Express 中间件没有正确路由并且抛出 next() 不是一个函数
【发布时间】:2021-01-15 01:55:12
【问题描述】:

尽管在我编写和测试它时它在我的本地机器上正常运行,但在使用 Docker 部署到我们的 UAT 环境时似乎失败了。我似乎无法追查为什么它给了我以下信息:

next() is not a function

我似乎也遇到了路由问题(再次仅在部署时),即使当路由是 /media/public 时,它似乎仍然会命中 /media 路由。

依赖

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

server.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

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

ROOT_SHARE=../media

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"]

准确的错误

任何帮助将不胜感激

【问题讨论】:

    标签: javascript node.js express next


    【解决方案1】:

    您的fileExists 被用作中间件和isAuthenticated 中调用的函数——在isAuthenticated 中它没有被传递res 或next。如果您确实将它传递到那里,您最终可能会遇到其他问题,因为这两个函数都调用res.status(status).send()。当这些函数没有 await 执行任何操作时,您还可以在这些函数上使用一些 async 关键字——这并没有破坏任何内容,只是浪费了几个字符:)。

    【讨论】:

      【解决方案2】:

      你打电话:

      fileExists(req);
      

      但是您对fileExists() 的实现希望您通过它(res, res, next) 而您没有通过它。因此,当fileExists() 尝试调用next() 时,您会收到错误next() is not a function。

      我不清楚您到底要做什么,但也许您可以更改为将(req, res, callback) 传递给fileExists(),然后在该回调中继续处理。这就是您自己手动调用中间件的方式,看起来您正在尝试这样做:

      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');
          }
      
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-05
        • 1970-01-01
        • 2015-03-24
        • 1970-01-01
        • 2020-09-03
        • 1970-01-01
        • 1970-01-01
        • 2012-07-13
        相关资源
        最近更新 更多