V
V
Vladimir2018-02-21 10:53:34
Nginx
Vladimir, 2018-02-21 10:53:34

How to upload file to server using koa?

What I use: koa(server) + koa-bodyparser, nginx - for static
What is needed:

  • on the client there is a form:
    form
    <form class="upload-form"><input type="file" name="file accept=".pdf"><input type="date" name="dateFrom"><input type="date" name="dateTo"><button class="button uploadBtn">Load</button></form>

  • I need to transfer its contents to the server in such a way as to save the file and get the rest of the data

What I did:
  • const xhr = new XMLHttpRequest;
      xhr.open('POST', '/some/url, true);
      xhr.send(new FormData(form));

    , and on the server used koa-multer to save the file. The nginx limiter worked - increased the file size limit. And here nuances arise: the multiter saves the file, but without an extension and with a randomly generated name.
    How to get the rest from the form because ctx.request.body is empty
  • my ajax
    const ajax = (params) => {
      params.beforeSend ? params.beforeSend() : null;
      const xhr = new XMLHttpRequest();
      xhr.open(params.method, params.url, true);
      xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
      if (params.req) {
        // if (typeof params.req !== 'object') {
        //   const data = {data: params.req};
        //   xhr.send(JSON.stringify(data));
        // } else {
        //   xhr.send(JSON.stringify(params.req));
        // }
        xhr.send(params.req); // вот тут строка, обратить внимание
      } else {
        xhr.send();
      }
      let promise = new Promise((res) => {
        xhr.onreadystatechange = function () {
          if (this.readyState === 4) {
            console.log(params.url, xhr.status);
            console.log(xhr.responseText);
    
            const response = JSON.parse(xhr.responseText).data;
            switch (xhr.status) {
              case 200:
                params.success(response);
                break;
              case 400:
              case 500:
                params.error(response);
                break;
              default:
    
            }
            res(true)
          }
        };
      });
    
      promise.then((result) => {
        params.complete && result ? params.complete() : null;
      })
    };
    const fd = new FormData(form);
    ajax({
        method: 'post',
        url: '/some/url',
        req: fd,
        success: function (dataOut) {
          console.log(dataOut);
        },
        error: function () {
          console.log('error');
        }
      });

    And here it is ambiguous: if I just send it, then, oddly enough, the bodyparser limiter works, which I could not remove with anything. If you do xhr.send(JSON.stringify(params.req)); , then again there is nothing in ctx.request.body and no file is saved.
  • And finally, I went through my form and simply saved everything into a separate object, which I sent to the server. In this case ctx.request.body = { file: { '0': {} },
    dateFrom: '2018-01-31',
    dateTo: '2018-02-13' }

I'm clearly not doing this thing the right way at all. Please explain what is happening)) and how to do it right. Give examples of working codes. Thanks

Answer the question

In order to leave comments, you need to log in

3 answer(s)
V
Vladimir, 2018-02-21
@MegaBatz

Thanks for the advice, but the output turned out to be the following:
- FormData had to be sent from the client in ajax without the line xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); and of course without JSON.stringify;
- then nginx itself parses the received data and puts it in the corresponding variables. I haven’t figured out how node works with them yet, but the fact is that nothing gets into ctx (at least I haven’t dug up anything);
- but! koa-multer still gets this data)) (I will also dig this module) and puts the data received from the form into ctx.req.file and ctx.req.body respectively. Further it is not difficult to rename the file.

A
Andrey Tsvetkov, 2018-02-21
@yellow79

There is a wonderful library that deals with just these things. Not only in the context of koa
https://www.npmjs.com/package/form-data

V
Vladimir Skibin, 2018-02-21
@megafax

You can use busboy in your desired middleware. And don't forget to specify enctype in the form

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question