6

When I post a multipart form,

<form name="acount_manage"  action="/update" enctype="multipart/form-data" method="post">
    <input type="file" name="file">
</form>

It throws:

Error: Unsupported content-type: multipart/form-data
at Object.<anonymous> (e:\...\node_modules\co-body\lib\any.js:51:15)

any.js:

/**
 * Module dependencies.
 */

var json = require('./json');
var form = require('./form');
var text = require('./text');

var JSON_CONTENT_TYPES = [
  'application/json',
  'application/json-patch+json',
  'application/vnd.api+json',
  'application/csp-report',
  'application/ld+json'

];

/**
 * Return a a thunk which parses form and json requests
 * depending on the Content-Type.
 *
 * Pass a node request or an object with `.req`,
 * such as a koa Context.
 *
 * @param {Request} req
 * @param {Options} [opts]
 * @return {Function}
 * @api public
 */

module.exports = function(req, opts){
  req = req.req || req;

  // parse Content-Type
  var type = req.headers['content-type'] || '';
  type = type.split(';')[0];

  // json
  if (~JSON_CONTENT_TYPES.indexOf(type)) return json(req, opts);

  // form
  if ('application/x-www-form-urlencoded' == type) return form(req, opts);

  // text
  if ('text/plain' == type) return text(req, opts);

  // invalid
  return function(done){
    var message = type ? 'Unsupported content-type: ' + type : 'Missing content-type';
    var err = new Error(message);
    err.status = 415;
    done(err);
  };
};

then,I changed the code

if ('application/x-www-form-urlencoded' == type) return form(req, opts);

to

if ('application/x-www-form-urlencoded' == type || 'multipart/form-data'==type) return form(req, opts);

no error ,but I can't get the request'data :

debug(this.request.files.file);

Result is undefined.

I am using KoaJs.

silkAdmin
  • 4,640
  • 10
  • 52
  • 83
lichao123125
  • 61
  • 1
  • 4

3 Answers3

2

For koa 2, try async-busboy to parse request body as co-busboy doesn't play well with promise based async.

Example from the docs:

import asyncBusboy from 'async-busboy';

// Koa 2 middleware
async function(ctx, next) {
  const {files, fields} = await asyncBusboy(ctx.req);

  // Make some validation on the fields before upload to S3
  if ( checkFiles(fields) ) {
    files.map(uploadFilesToS3)
  } else {
    return 'error';
  }
}
silkAdmin
  • 4,640
  • 10
  • 52
  • 83
  • [async-busboy](https://github.com/m4nuC/async-busboy) has an [issue generating ReadStreams](https://github.com/m4nuC/async-busboy/issues/1), so it's not reliable for multiple files upload yet. – Nik Sumeiko Apr 24 '16 at 09:57
2

Try koa-body library.

Example:

Put this middleware BEFORE the route middleware:

app.use(require('koa-body')({
    formidable:{
        uploadDir: __dirname + '/public/uploads', // directory where files will be uploaded
        keepExtensions: true // keep file extension on upload
    },
    multipart: true,
    urlencoded: true,
}));

Then use in route middleware

async function(ctx, next) {
    ctx.request.body.files.file  // file is the input name
}

This code is for KoaJs 2, but this library works with KoaJs 1 too.

Valera
  • 2,665
  • 2
  • 16
  • 33
0

Okay. First of all the code you are posting is the source code from co-body so adding in multipart/form-data isn't magically going to force this package to handle multi part data if it wasn't built to do so.

Rather than using co-body you can use co-busboy which was built to handle multipart/form-data.

Peadar Doyle
  • 1,064
  • 2
  • 10
  • 26