Как загрузить файл на сервер с помощью koa?

Что использую: koa(сервер) + koa-bodyparser, nginx - для статики
Что необходимо:
  • на клиенте есть форма:
    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>

  • ее содержимое мне нужно передать на сервак таким образом, что бы сохранить файл и получить остальные данные

Что я делал:
  • const xhr = new XMLHttpRequest;
      xhr.open('POST', '/some/url, true);
      xhr.send(new FormData(form));

    ,а на сервере использовал koa-multer для сохранения файла. Сработал ограничитель nginx - повысил лимит объема файлов. И тут возникают нюансы: мультер файл сохраняет, но без расширения и с именем случайно сгенерированным.
    Как получить остальное из формы, ибо ctx.request.body - пуст
  • мой 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');
        }
      });

    И вот двойственно: если делаю просто отправку, то как ни странно, срабатывает ограничитель bodyparser-а, который я снять ничем не смог. Если же сделать xhr.send(JSON.stringify(params.req)); , то опять в ctx.request.body ничего нет и никакой файл не сохраняется.
  • И последнее, я проходился по своей форме и просто сохранял все в отдельный объект, который и отправлял на сервер. В этом случае ctx.request.body = { file: { '0': {} },
    dateFrom: '2018-01-31',
    dateTo: '2018-02-13' }



Я явно делаю эту вещь вообще не так как следует. Объясните пожалуйста что происходит)) и как правильно поступать. Приведите примеры рабочих кодов. Спасибо
  • Вопрос задан
  • 604 просмотра
Решения вопроса 1
MegaBatz
@MegaBatz Автор вопроса
Спасибо за советы, но выход оказался следующий:
- с клиента в аджаксе FormData надо было отправлять без строки xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); и конечно без JSON.stringify;
- далее nginx уже сам парсит полученные данные и кладет их в соответственные переменные. Как node с ними работает я еще не разбирался, но факт в том что в ctx ничего не попадает (по крайней мере я ничего не накопал);
- но! koa-multer таки достает эти данные)) (тоже еще буду копать этот модуль) и кладет полученные из формы данные соответственно в ctx.req.file и ctx.req.body. Далее уже не сложно переименовать файл.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
yellow79
@yellow79
Senior Software Engineer
Есть замечательная библиотечка, которая занимается как раз этими делами. Не только в контексте koa

https://www.npmjs.com/package/form-data
Ответ написан
Комментировать
megafax
@megafax
web-программист
Можете использовать busboy в нужном мидлваре. И еще не забудьте в форме указать enctype
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы