使用 busboy 从 Express 应用程序中的 bodyParser() 迁移?

Migrating away from bodyParser() in Express app with busboy?

作为 Nodejs 的新手,我没有真正阅读良好的安全实践就直接开始编写一个简单的应用程序。我刚刚发现对所有路由使用 bodyParser() 实际上是 a bad thing because it allows for DOS attack using multipart files.

建议的修复方法是根据路由仅加载特定模块。即,对于多部分文件上传,使用 multipart。对于没有文件上传(即文本表单提交)的常规 POST,请使用 express.json(), express.urlencoded().

或者另一种选择是使用 busboy with connect-busboy。但我感到困惑的是我如何指定哪条路线应该处理多部分数据,哪条路线不应该?否则,我不会遇到与 bodyParser 相同的问题吗?

此外,busboy 文档说它不处理 GET:

If you find that req.busboy is not defined in your code when you expect it to be, check that the following conditions are met. If they are not, req.busboy won't be defined:
  1. The request method is not GET or HEAD

因此,我更加困惑如何在 GET 中解析 params。我认为 bodyParser 为我做了这个,所以我可以使用 req.params.

访问数据

例如,我将如何使用这个简单的应用程序从 bodyParser() 迁移到 busboy/connect-busboy

var express = require('express');
var app = express();
var http = require('http').Server(app);

var bodyParser = require('body-parser');
app.use(bodyParser.json());

var busboy = require('connect-busboy');
app.use(busboy());

// How to use busboy to prevent multipart files here?
app.post("/form_data_no_fileupload", function(req, res) {
    var somedata = req.body.somedata;
});

// Use busboy to handle both regular form data + fileuploads 
app.post("/form_data_AND_fileupload", function(req, res) {

});

// What would handle GET without bodyparser?
app.get("/get_something", function(req, res) {
    var params = req.params;
});

http.listen(3000, function() {});

[How] I can specify which route should handle multipart data and which should not?

所有快递' routing methods allow for providing middleware specific to the route. This includes Router methods.

app.METHOD(path, callback [, callback ...])

根据单个路由的预期主体,您可以使用不同的模块来处理它们中的每一个(而不是使用 app.use() 将它们应用于整个应用程序)。

var express = require('express');
var app = express();
var http = require('http').Server(app);

var bodyParser = require('body-parser');
var busboy = require('connect-busboy');

app.post("/form_data_no_fileupload",
    bodyParser.urlencoded(),
    function(req, res, next) {
        // check that the request's body was as expected
        if (!req.body) return next('route'); // or next(new Error('...'));

        // ...
    });

app.post("/form_data_AND_fileupload",
    busboy({
        limits: {
            fileSize: 10 * 1024 * 1024
        }
    }),
    function(req, res, next) {
        // check that the request's body was as expected
        if (!req.busboy) return next('route'); // or next(new Error('...'));

        // ...
    });

// ...

Furthermore, busboy docs says it does not handle GET.

So, I'm even more confused how I would parse params in a GET.

Busboy 和 BodyParser 设计用于读取和解析请求的正文,GET and HEAD requests aren't expected to have

对于此类请求,参数只能在query-string within the URL, which Express parses itself. They're available via req.query.

内传递
app.get('/get_something', function () {
    console.log(req.originalUrl);
    // "/get_something?id=1

    console.log(req.query);
    // { id: "1" }
});

req.params 表示路由在路径中匹配的任何占位符。无论采用何种方法,这些都适用于任何路线。

app.get('/thing/:id', function (req, res) {
    console.log(req.originalUrl);
    // "/thing/2"

    console.log(req.params);
    // { id: "2" }
});