Koa2 forward file upload interface

I used koa2 to do an interface proxy layer, and now I have a problem that the forwarding file upload is not successful.
my expectation is that the web page calls form to request uploading files to the koa layer, and the Koa layer is using the axios request Java interface to send the received content to the Java.

now all other APIs can be forwarded smoothly, but the upload interface is not. I would appreciate it if I asked my friends for help.

I used koa-body middleware;

module.exports = async ctx => {
  let {data, status} = await ctx.axios({
    url: `/upload`,
    method: "post",
    data: ctx.request.files
  })
  ctx.body = data
  ctx.status = status
}
Apr.21,2022

2019.11.25 update
almost a year has passed. Some time ago, I found that there still seems to be a problem with the answer I wrote before. These two days, I re-searched the question of uploading and forwarding files, and found that there are only a handful of other places except here. Let's update the latest solution. I believe I am not the only one who has encountered this problem.

first of all, in order to solve this problem, we mainly rely on three libraries: form-data and koa2-formidable and axios :
koa2-formidable : the purpose is to obtain the formData passed from the original interface of koa. Previously, we found that formData could not be obtained by using koa-bodyparser . Use the following to register this module in the entry js file (app.js here):

form-data : there is no formData object in nodejs, so you need this library to assemble formData.

axios : make an interface request

The versions of the three modules in

package.json are as follows:

"koa": "^2.5.3"
"axios": "^0.17.1"
"koa2-formidable": "^1.0.2"
"form-data": "^3.0.0"

entry file:

app.js

const bodyParser = require('koa-bodyparser');
const formidable = require('koa2-formidable');

app.use (formidable ({}))
// ctx.body,route
app.use(bodyParser({
  enableTypes: ['json', 'form', 'text'],
  extendTypes: {
    text: ['text/xml', 'application/xml']
  }
}));

...

the local code for interface forwarding is as follows:

upload.js

const FormData = require('form-data');
const fs = require('fs');
const axios = require("axios");

async function upload (ctx) {
    const form = new FormData();
    const file = ctx.request.files.file; // formidableformData'file'
    form.append('smfile', fs.createReadStream(file.path) // formData
    
    // axiosnode-requestformDataaxios
    const r = await axios({
        method: "post",
        url: "https://example/api/upload",
        data: form,
        headers: { ...form.getHeaders() }
      });
      
      //
}

exports.upload = upload
< hr >

Today, I also encountered the same problem as the landlord. Post my solution. If the request parameters of the front end are the same as the parameters of the final upload interface, you can directly use ctx.req.pipe to pass the parameters passed from the front end, so that you do not need to use any other processing:

const request = require('request');
router.post('/upload', async (ctx) => {
  const res = await ctx.req.pipe(request.post(`https://example.com`)) // 
  ctx.body = res
});

your files is not the content of the file, but some local information where the file exists


middleware plays a transitional role, so pay attention to the way it is delivered. Reference code is as follows:

module.exports = async ctx => {
  let formdata = new FormData()
  formdata.append('file', ctx.request.files.file)
    
  let {data, status} = await ctx.axios({
    url: `/upload`,
    method: 'post',
    data: formdata,
    headers: {
        'Content-Type': 'multipart/form-data'
    }
  })
}
Menu