Как проанализировать двоичные данные ("multipart / form-data") в KOA? - PullRequest
0 голосов
/ 07 декабря 2018

Если я отправляю POST-запрос с текстовыми опциями, все ОК:

query from front-end:

const request = require("request")
const options = {
 method: 'POST',
 url: 'http://localhost:4000/user',
 headers:    form: { data: '12345' }
 }

На стороне сервера (KOA) я могу получить проанализированные данные запроса:

ctx.request.method: "POST"
ctx.request.originalUrl: "user"
ctx.request.body.data: "12345"

Ноесли я отправлю запрос POST с двоичными данными (файл):

const fs = require("fs");
const request = require("request");
const options = { method: 'POST',
  url: 'http://localhost:4000/user',
  headers: 
   {
     'content-type': 'multipart/form-data},
  formData: 
   { '': 
      { value: 'fs.createReadStream("F:\\image.jpg")',
        options: 
         { filename: 'F:\\image.jpg',
           contentType: null }
 } } };

Я не знаю, как я могу получить доступ к этим двоичным данным ("image.jpg) на серверной части (KOA),в ctx.request есть любое поле с этими данными ...

1 Ответ

0 голосов
/ 17 декабря 2018

Вы можете использовать busboy для этого. Я написал суть для этого , но я собираюсь встроить его сюда с некоторыми комментариями.

Давайте создадим помощник для анализа файла удобным для обещаний способом.

// parse.js
import Busboy from 'busboy'

/**
 * Parses a single file from a Node request.
 *
 * @param  {http.IncommingRequest} req
 * @return {Promise<{ file: Stream, filename: string>}
 */
export default function parse (req) {
  return new Promise((resolve, reject) => {
    const busboy = new Busboy({
      headers: req.headers,
      limits: {
        files: 1 // allow only a single upload at a time.
      }
    })

    busboy.once('file', _onFile)
    busboy.once('error', _onError)
    req.pipe(busboy)

    function _cleanup () {
      busboy.removeListener('file', _onFile)
      busboy.removeListener('error', _onError)
    }

    function _onFile (fieldname, file, filename) {
      _cleanup()
      resolve({ file, filename })
    }

    function _onError (err) {
      _cleanup()
      reject(err)
    }
  })
}

Теперь нам нужно его использовать.Предположим, вы хотите загрузить на AWS S3.

import Koa from 'koa'
import parse from './busboy'
import AWS from 'aws-sdk'

const app = new Koa()

const s3 = new AWS.S3({ 
  params: { Bucket: 'myBucket' } 
})

// Assuming this is a route handler.
app.use(async (ctx) => {
  const { file, filename } = await parse(ctx.req)
  // `file` is a Stream. Pass this to S3, Azure Blob Storage or whatever you want.
  // `filename` is the file name specified by the client.
  const result = await s3.upload({
    Key: filename,
    Body: file
  }).promise()

  ctx.body = result
})

Для краткости, вы загрузите файл, используя axios на клиенте.

// `file` is a DOM File object.
function upload (file) {
  const data = new window.FormData()
  data.append('file', file, file.name)
  return axios.post('/upload', data)
}
...