Node js receive file in HTTP request

2020-07-20 05:00发布

问题:

I try to create a server, which can receive a file from an HTTP request. I use Postman as user agent and I add a file to the request. This is the request:

POST /getfile HTTP/1.1
Host: localhost:3000
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Cache-Control: no-cache
Postman-Token: 9476dbcc-988d-c9bd-0f49-b5a3ceb95b85

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="test.xls"
Content-Type: application/vnd.ms-excel


------WebKitFormBoundary7MA4YWxkTrZu0gW--

But when the request reaches the server I can not find the file in it (I mean in the request). I tried to receive it from the body part of the request, but it returned > {} <. I tried to figure out, how can I refer to the name of the file, but unfortunately I can not find any reference in the request header for the name of the file...

Can anybody help me to find out, what should I do?

回答1:

As a follow up to my comment, you can use the multer module achieve the thing that you want: https://www.npmjs.com/package/multer

const express = require('express');
const multer = require('multer');

const app = express();
const upload = multer();

app.post('/profile', upload.array(), function (req, res, next) {
  // req.body contains the text fields 
});


回答2:

var app = require('express')();
var multer = require('multer');
var upload = multer();

app.post('/your_path', upload.array(), function (req, res, next) {
  // req.files is array of uploaded files
  // req.body will contain the text fields, if there were any
});



回答3:

You need to parse the form data from the request. There are a few packages that solves this problem, notably formidable, busboy (or busboy-connect), parted and flow.

Here's a solution using formidable, it is my preferred solution for things like image uploads because it saves to disk. If you just want to read the file, you can use one of the other packages above.

Install formidable

npm install formidable --save

Then, in your server, you will have to parse the data from the client:

// Somewhere at the start of your file
var IncomingForm = require('formidable').IncomingForm

// ...

// Then in your request handler
var form = new IncomingForm()
form.uploadDir = 'uploads'
form.parse(request, function(err, fields, files) {
  if (err) {
    console.log('some error', err)
  } else if (!files.file) {
    console.log('no file received')
  } else {
    var file = files.file
    console.log('saved file to', file.path)
    console.log('original name', file.name)
    console.log('type', file.type)
    console.log('size', file.size)

  }
})

A few things to note:

  • formidable saves files with new names, you can use fs to rename or move them
  • you can set form.keepExtensions = true if you want saved files to keep their extensions