2015-11-17 18 views
13

Perché ho trascorso un po '(troppo) tempo a capire questo semplice requisito. Sto documentando qui il modo per ottenere l'analisi del corpo multipart/form-data con Koa.Come analizzare il corpo multipart/form-data con Koa?

Nel mio caso, il motivo della confusione è stato il numero di alternative disponibili là fuori:

e volevo per trovare il più minimalista/vicino a express/koa/node modo/filosofia del fare le cose.

Quindi eccoci qui. Sotto. Nella risposta accettata. Spero che questo ti aiuti.

risposta

8

È necessario utilizzare koa-multer come indicato nello Koa wiki ufficiale.

Quindi una semplice configurazione sarà simile:

const koa = require('koa'); 
const multer = require('koa-multer'); 

const app = koa(); 

app.use(multer()); 

app.use(function *() { 
    this.body = this.req.body; 
}); 

Un paio di note:

  • Multer sarà solo analizzare i corpi di richieste di tipo multipart/form-data
  • Avviso l'uso di this.req.body al posto di Koa sovralimentato this.request (non sicuro se questo è intenzionale t questo è fonte di confusione per certo ... mi aspetterei che il analizzato body essere disponibile su this.request ...)

ed inviando questo modulo HTML come FormData:

<form> 
    <input type="hidden" name="topsecret" value="1"> 
    <input type="text" name="area51[lat]" value="37.235065"> 
    <input type="text" name="area51[lng]" value="-115.811117"> 
    ... 
</form> 

Sarebbe darà accesso a proprietà nidificate come previsto:

// -> console.log(this.req.body) 
{ 
    "topsecret": 1, 
    "area51": { 
    "lat": "37.235065", 
    "lng": "-115.811117", 
    } 
} 
+0

Io in realtà [chiesto perché] (https://github.com/koa-modules/multer/issues/2) analizzata corpo non disponibile su 'this.request '. – eightyfive

3

sono andato attraverso la stessa indagine di te e qui ci sono altri modi per raggiungere multipart/form-data corpo parsing con Koa.

co-aiuto cameriere:

var koa = require('koa'); 
var parse = require('co-busboy'); 

const app = koa(); 

app.use(function* (next) { 
    // the body isn't multipart, so busboy can't parse it 
    if (!this.request.is('multipart/*')) return yield next; 

    var parts = parse(this), 
     part, 
     fields = {}; 
    while (part = yield parts) { 
    if (part.length) { 
     // arrays are busboy fields 
     console.log('key: ' + part[0]); 
     console.log('value: ' + part[1]); 

     fields[part[0]] = part[1]; 
    } else { 
     // it's a stream, you can do something like: 
     // part.pipe(fs.createWriteStream('some file.txt')); 
    } 
    } 

    this.body = JSON.stringify(fields, null, 2); 
}) 

koa-corpo:

var koa = require('koa'); 
var router = require('koa-router'); 
var koaBody = require('koa-body')({ multipart: true }); 

const app = koa(); 

app.use(router(app)); 

app.post('/', koaBody, function *(next) { 
    console.log(this.request.body.fields); 

    this.body = JSON.stringify(this.request.body, null, 2); 
}); 

In entrambi i casi si avrà una risposta come:

{ 
    "topsecret": 1, 
    "area51": { 
    "lat": "37.235065", 
    "lng": "-115.811117", 
    } 
} 

Ma personalmente, Preferisco il modo in cui k o un corpo. Inoltre, è compatibile con altri middleware come koa-validate.

Inoltre, se si specifica un dir di upload al KOA-corpo, salverà il file caricato per voi:

var koaBody = require('koa-body')({ 
    multipart: true, 
    formidable: { uploadDir: path.join(__dirname, 'tmp') } 
}); 
10

Per Koa2, è possibile utilizzare async-busboy come altre soluzioni dont sostenere promesse o async/attendi.

Esempio dalla documentazione:

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'; 
    } 
} 
+0

Utilizzare con campi automatici. var parts = attendi asyncBusboy (ctx.req, { autoFields: true // salva i campi in parts.field (s) }); –