Fetch API and multer error while uploading file
Asked Answered
C

3

12

I'm trying to use fetch API to upload files to a node.js server (I'm using github's pollyfill if it has something to do with it: https://github.com/github/fetch).

The request is done like this:

const data = new FormData();
data.append('file', file);
return fetch(this.concatToUrl(url), {
  method: 'post',
  headers: Object.assign({}, this.getHeaders(), {'Content-Type': 'multipart/form-data'}),
  body: data,
});

On the server side I have, this declaration of route:

app.post('/media', upload.single('file'), mediaRoutes.postMedia);

And trying to get the file like this:

exports.postMedia = function(req, res) {
  console.log('req.file', req.file, req.files, req.body);
  return res.sendStatus(200);
}

But req.file is not being filled.

Also I'm getting this error from express side:

Error: Multipart: Boundary not found
[2]     at new Multipart (/Users/jmanzano/Development/web/test/node_modules/busboy/lib/types/multipart.js:58:11)
[2]     at Multipart (/Users/jmanzano/Development/web/test/node_modules/busboy/lib/types/multipart.js:26:12)
[2]     at Busboy.parseHeaders (/Users/jmanzano/Development/web/test/node_modules/busboy/lib/main.js:64:22)
[2]     at new Busboy (/Users/jmanzano/Development/web/test/node_modules/busboy/lib/main.js:21:10)
[2]     at multerMiddleware (/Users/jmanzano/Development/web/test/node_modules/multer/lib/make-middleware.js:32:16)
[2]     at Layer.handle [as handle_request] (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/layer.js:95:5)
[2]     at next (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/route.js:131:13)
[2]     at Route.dispatch (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/route.js:112:3)
[2]     at Layer.handle [as handle_request] (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/layer.js:95:5)
[2]     at /Users/jmanzano/Development/web/test/node_modules/express/lib/router/index.js:277:22
[2]     at Function.process_params (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/index.js:330:12)
[2]     at next (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/index.js:271:10)
[2]     at cors (/Users/jmanzano/Development/web/test/node_modules/cors/lib/index.js:178:7)
[2]     at /Users/jmanzano/Development/web/test/node_modules/cors/lib/index.js:228:17
[2]     at originCallback (/Users/jmanzano/Development/web/test/node_modules/cors/lib/index.js:217:15)
[2]     at /Users/jmanzano/Development/web/test/node_modules/cors/lib/index.js:222:13
[2]     at optionsCallback (/Users/jmanzano/Development/web/test/node_modules/cors/lib/index.js:203:9)
[2]     at /Users/jmanzano/Development/web/test/node_modules/cors/lib/index.js:208:7
[2]     at Layer.handle [as handle_request] (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/layer.js:95:5)
[2]     at trim_prefix (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/index.js:312:13)
[2]     at /Users/jmanzano/Development/web/test/node_modules/express/lib/router/index.js:280:7
[2]     at Function.process_params (/Users/jmanzano/Development/web/test/node_modules/express/lib/router/index.js:330:12)

And this is the configuration via middlewares:

app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(expressValidator());
app.use(logger('dev'));
app.use(cookieParser());
app.use(methodOverride());
app.use(passport.initialize());
app.use(passport.session());
app.set('JWTSuperSecret', jwtConfig.secret);

if (process.env.NODE_ENV !== 'production') {
  app.use(cors());
}

Also, this is correctly working with POSTMAN. So, I think I'm doing something wrong with the request.

Thanks!

Chapel answered 4/3, 2016 at 12:1 Comment(0)
D
17

For those stumbling upon this post who have the error when using postman make sure to not specify the content-type in the headers.

Disburse answered 6/1, 2017 at 2:44 Comment(0)
S
11

There is no need to assign a header {Content-Type': 'multipart/form-data'}: the browser substitutes its own.

But if you expose it, then it is not specified boundary after content-type:multipart/form-data; boundary=... in Request Headers before Request Payload and that is causing the error on the server-side.

If you open the browser console and see the headers, it will be seen.

So, just:

fetch(this.concatToUrl(url), {
  method: 'post',
  body: data,
});

Or, if you need custom headers you can add them like this:

var headers = Object.assign({},
                            {'content-type': 'application/json'},
                            this.getHeaders(), 
                            {'Content-Type': 'multipart/form-data'}
);

   // Removal should be case insensitive, or in any case, the header will be included:


Object.keys(headers)
      .forEach( function(k) { 
         if (k.toLowerCase()==='content-type') delete headers[k] 
      })

const data = new FormData();
data.append('file', file);
return fetch(this.concatToUrl(url), {
  method: 'post',
  headers: headers,
  body: data,
});
Shame answered 4/3, 2016 at 15:29 Comment(2)
The problem with this approach is that I have to set more custom headers (to allow JWT auth for example). How can I achieve that?Chapel
Just prowess property content-type from the list of headers. See update.Shame
M
0

make sure you give correct name attribut to your input file. If multer waite file name "image" , you must set

Mirandamire answered 25/1, 2024 at 11:2 Comment(1)
Please add a minimal code example in order for your answer to be more understandable /usefulSeanseana

© 2022 - 2025 — McMap. All rights reserved.