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

formidable is stuck at parse function's callback #948

Closed richard-here closed 11 months ago

richard-here commented 11 months ago

Support plan

Context

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

I am trying to create an API endpoint that accepts uploading an Excel file in Node.js with Express and Formidable. After uploading the Excel file, I will parse the content of the file with another package to insert the parsed data to MongoDB using Mongoose. Currently, I am stuck at the parse function of Formidable.

const express = require('express')
const cors = require('cors')
const { IncomingForm } = require('formidable')

const app = express()
app.use(cors({ origin: true }))
app.use(express.json()) // Commenting this line does not make it work either

const router = express.Router()
router.post(
  '/upload',
  (req, res, next) => {
    const form = new IncomingForm({})
    console.log(form)
    form.parse(req, (err, fields, files) => {
      if (err) {
        throw err
      }
      console.log(fields)
      console.log(files)
      res.send('hi')
    })
  }
)

app.use('/', router)

module.exports = app

To call the API endpoint on Postman, here's what I did. The uploaded file is 15KB. image image

What was the result you got?

The request got stuck when I tried to hit that API endpoint using Postman. It does log the console.log(form) statement, but anything beyond that seems to never run.

What result did you expect?

To be able to log what fields and files contain as well as sending a hi as a response in Postman.

eschaefer commented 11 months ago

Just came here with the exact same use case. The callback never resolves, no error either.

Just to make it simpler without all the postman/insomnia UI:

curl --request POST \
  --url <my url> \
  --header 'Content-Type: multipart/form-data' \
  --form field1=eee \
  --form field2=text

Results in parse hanging.

GrosSacASac commented 11 months ago

Try again with node v20, and without express

eschaefer commented 11 months ago

@GrosSacASac just curious but... why? The docs say node > 10.13 is supported, and there is explicit express integration support in the docs.

GrosSacASac commented 11 months ago

Yes, but first of all we need to find the source of the problem.

Since it works for me (I just tested the curl example) I conclude that it must something that we have different. which is node version or express.

Once we find the source of the problem we can try to find the solution or update the docs

soapproject commented 11 months ago

Face the same issue today, but it turned out I forget to disable the nextjs bodyParser.

export const config = {
  api: {
    bodyParser: false,
  },
};
richard-here commented 11 months ago

I have found the main issue for my case. It wasn't because of the Node version or the Express version, but instead on which I ran my Express app: Google Cloud Functions.

It turns out that Google Cloud Functions implement some middleware that converts inputs that are files into raw data type (Buffer) in req.rawBody (full description here: https://stackoverflow.com/a/47319614). It seems that Formidable requires the data type unmodified, and as the data is automatically modified when running on an Express app on Google Cloud Functions, I concluded that my case is not the right use case to use Formidable.

At the same time, I tried running Formidable on a regular Express app and it worked with the Node version I provided in the original issue submission.

For others facing the same issue, you can instead parse the raw data using Busboy.

GrosSacASac commented 11 months ago

Next time test locally before making an issue.

Someone made https://github.com/Amit-A/formidable-serverles that uses req.rawBody. I am not sure that it is a clean solution.

GrosSacASac commented 11 months ago

related https://github.com/node-formidable/formidable/issues/594

JulianKingman commented 2 months ago

Sorry to resurrect this, but shouldn't formidable throw some kind of error if it can't parse the request? Would a PR exposing the error be accepted? Could blow things up, but it's better than silent failure.