具有 JSON 和二进制数据传递功能的 Express Body Parser

Express Body Parser with both JSON and binary data passing capability

在我的 express app 路由器中,我有接受 POST 请求 JSON 数据以及二进制数据的路由。问题是当我使用正文解析器传递 JSON 数据时,它也将二进制数据视为 JSON 并在 POSTing 二进制数据时出错。即当我使用:

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false}));

当我删除它时,它只适用于二进制数据。以下是我 POSTing 二进制文件的路径。

router.post('/file', function (req, res) {
    var gridfs = app.get('gridfs');
    var writeStream = gridfs.createWriteStream({
        filename: 'file_name_here'
    });
    writeStream.on('close', function (file) {
        res.send(`File has been uploaded ${file._id}`);
    });
    req.pipe(writeStream);
});

我也试过将这个文件路由移动到其他路由器。在那种情况下,当我没有设置任何关于正文解析器的内容时​​,它仍然会给出相同的错误。

一个正确的修复方法是在设置正文解析器之前将此文件路径放置在我的主要 app.js 中。 但我认为这不是好的方法。我希望这些路由在单独的文件中。

那么我在这里缺少什么?任何替代方案也将不胜感激。

编辑

根据回答,我首先区分了需要正文解析和不需要正文解析的路由器。还从我的主要 app.use() 中删除了 bodu 解析器现在在我需要主体解析器的路由器中,我添加了这两行。但是行为是一样的。

当我添加这两行时,只有 JSON reqquest 有效,而当我删除时,只有二进制 POST req.作品。

这是我更新后的代码:

app.js

    const express = require('express');
const app = module.exports = express();
const bodyParser = require('body-parser');

const port = 8080;


// //parsing incoming requests using body-parser middlewares
// app.use(bodyParser.json());
// app.use(bodyParser.urlencoded({ extended: false}));


//adding routes
app.use(require('./routes/additionRouter'));
app.use(require('./routes/mediaRouter'));

//catch 404 file not found here
app.use((req, res, next) => {
    const err = new Error('Page Not Found');
    err.status = 404;
    next(err);
});

//Error Handler
app.use((err, req, res, next) => {
    res.status(err.status || 500);
    res.send(err.message);
});

app.listen(port, () => {console.log('Server listening on port: ' + port)});

additionRouter.js

const express = require('express');
const router = express.Router();

var exported = require('../config/dbConnection');

 const bodyParser = require('body-parser');

 // parsing incoming requests using body-parser middlewares
 router.use(bodyParser.json());
 router.use(bodyParser.urlencoded({ extended: false}));

//Endpoint for adding new challenge
router.post('/endpoint1', (req, res, next) => {

});

module.exports = router; 

mediaRouter.js

    const express = require('express');
const mediaRouter = express.Router();
const exported = require('../config/dbConnection');

exported.cb((gridfs) => {
    //For adding media files to database named 'mediadb'
    //POST http://localhost:8080/file
    mediaRouter.post('/file', function (req, res) {
        // var gridfs = app.get('gridfs');
        var writeStream = gridfs.createWriteStream({
            filename: 'file_name_here'
        });
        writeStream.on('close', function (file) {
            res.send(`File has been uploaded ${file._id}`);
        });
        req.pipe(writeStream);
    });

    //GET http://localhost:8080/file/[mongo_id_of_file_here]
    mediaRouter.get('/file/:fileId', function (req, res) {
        // var gridfs = app.get('gridfs');
        gridfs.createReadStream({
            _id: req.params.fileId // or provide filename: 'file_name_here'
        }).pipe(res);
    });

});


module.exports = mediaRouter;

通过指定

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false}));

您的整个应用程序都使用主体解析器中间件。您可以创建另一个中间件来处理是否使用正文解析器。例如:

const bodyParse = bodyParser.json();
app.use((req, res, next) => {
    if(req.originalUrl == "restOfUrl/file") next();
    else bodyParse(req, res, next);
});