node-formidable / formidable

The most used, flexible, fast and streaming parser for multipart form data. Supports uploading to serverless environments, AWS S3, Azure, GCP or the filesystem. Used in production.
MIT License
7k stars 680 forks source link

JSON array directly in request body is interpreted as Object #850

Closed Akxe closed 2 years ago

Akxe commented 2 years ago

Support plan

Context

What are you trying to achieve or the steps to reproduce?

function formidableMiddleWare(options = {}) {
    return (req, _res, next) => {
        const form = formidable(options);

        form.parse(req, (err, fields, files) => {
            if (err) {
                logger.error('Parsing of form', options, err);

                next(err);
                return;
            }

            req.body = fields
            next();
        });
    };
};
app.post(
  '/form',
  formidableMiddleWare({
    // Do not accept any file by default!
    filter: () => false,
  }),
  (req, res) => {
    res.json({
      req,
      isArray: Array.isArray(req),
    });
  },
);

What was the result you got?

The result of form.parse is an Object not Array

What result did you expect?

The result of form.parse should be an Array.

GrosSacASac commented 2 years ago

Try again with version 3

Akxe commented 2 years ago

I cannot use v3:

C:\Users\akxe\Documents\Programming\rita\node_modules\@nrwl\node\src\executors\node\node-with-require-overrides.js:16
        return originalLoader.apply(this, arguments);
                              ^
Error [ERR_REQUIRE_ESM]: require() of ES Module C:\Users\akxe\Documents\Programming\rita\node_modules\formidable\src\index.js from C:\Users\akxe\Documents\Programming\rita\dist\apps\server\main.js not supported.

I use

GrosSacASac commented 2 years ago

Don't use webpack

Akxe commented 2 years ago

How is this a solution to this problem?

tunnckoCore commented 2 years ago

@Akxe use v3, and probably something like that

https://github.com/tunnckoCore/opensource/blob/75e2766eea27ca4bd01b7e10b3760aecccee1600/%40tunnckocore/execa/src/main.js#L9-L19

with esm to load the formidable v3 esm.

const req = require('esm')(module);
const formidable = req('formidable');
tunnckoCore commented 2 years ago
What was the result you got?

The result of form.parse is an Object not Array

Aside from the other comment with possible temporary solution.

Well, i think it's because when there's only one it's an json, when there are multiple it's an array. I don't like that change in behaviors too, but.. i don't like single item arrays either.


uh, wait a sec, why is that isArray: Array.isArray(req), ?

aaand, what you mean with that title, i still don't get it. Is fields an array before you assigning it to the req.body? and what you mean with that it's interpreted as object

Akxe commented 2 years ago

@tunnckoCore It was meant to be req.body. The problem is not isolated to single-element arrays. It is because the result is by default an Object and properties are added to it as they come. The fix would be to check if the body has only numeric values or to actually check the first character of the body.

tunnckoCore commented 2 years ago

@Akxe well, i'm really struggling to understand all that.

I looked at the code and yea, fields is always an object, what it should be? Why it shouldn't be? I don't get what the problem is at all. In parse it comes as object, then you assign it to req.body, then it's an object and not an array which is normal. And what?

Akxe commented 2 years ago

Hey, the point is that if you pass an array to body of normal requests the BodyParser will give an array in the NodeJS part, but if you pass the same array to the FormData, it will be transformed to an object. It actually fought me off guard, since I had to switch from body request to formData (because I wanted to send a file); The array function I expected to be present was suddenly not present even though there was no indication that it should not.

TLDR; For consistency's sake, it should mimic BodyParser/JSON.stringify as close as possible.

tunnckoCore commented 2 years ago

can you give actual example and data.