Как получить массивы/объекты, отправленные через форму паруса.js (с enctype multipart / form-data)

Я вложил информацию в свои формы, чтобы соответствовать моим моделям, это значительно упрощает вещи на бэкэнде, но я не могу узнать, как получить массивы или объекты (или комбинацию обоих) в парусах.js

предполагая, что у меня есть такая форма

Примечание: поддержка "multipart / form-data" полностью необходима.

<form action="/articles" method="post" enctype="multipart/form-data">
    <input type="file" name="status" value="published">
    <!-- Entry 0 -->
    <input(type="text" name="entries[0][title]" value="Entry 1")
    <input(type="text" name="entries[0][content]" value="Entry 1 Content...")
    <!-- Entry 1 -->
    <input(type="text" name="entries[1][title]" value="Entry 2")
    <input(type="text" name="entries[1][content]" value="Entry 2 Content...")
    <!-- images -->
    <input type="file" name="images[]">
    <input type="file" name="images[]">
</form>

Я ожидаю получить такой объект в req.парамы.all () obj

{
 status: 'published',
 entries: [
   {title: 'Entry 1', content: 'Entry 1 Content...'},
   {title: 'Entry 2', content: 'Entry 2 Content...'}
 ]
}

теперь при вызове req.params.all()/req.body вместо этого я получаю:

{
 status: 'published',
 'entries[0][title]': 'Entry 1'
 'entries[0][content]': 'Entry 1 Content...'
 'entries[1][title]': 'Entry 2'
 'entries[1][content]': 'Entry 2 Content...'
 'entries[0][title]': 'Entry 1'
}

вызов req.file('images[]') дает правильное поведение. Я проверяю ._files свойство того, что возвращается этим fn и показывает мои 2 изображения там. Использование скобок здесь кажется действительно странным, но это то, что есть.

Я думаю, это связано с тем, что я получаю с Треб.парамы.all () я могу дополнительно проанализировать это, но это будет хакерским и хрупким, если что-то изменится в будущем. В любом случае это обычная картина в любом веб-приложении и поддерживается многими языками и фреймворками, поэтому мне действительно странно, что кажется невозможным получить то, что мне нужно, с помощью простых парусов.функциональность js, поэтому я предполагаю, что я не делаю что-то так, как должно, или что я что-то упускаю. Пожалуйста, укажите мне в правильном направлении, и если на самом деле паруса не поддерживают это основное поведение гнездования, то как я должен действовать?

отправка необработанного контента через Javascript не является опцией здесь (Если это невозможно в противном случае), как предложено в третьем ответе на этот вопрос: возможно ли в Sailsjs построить более сложные модели Делая это таким образом, по крайней мере, для текстовых полей я получаю правильный вывод, не уверен с изображениями, так как я тестировал через postman с rawdata.

Edit: До сих пор я пытался изменить синтаксический анализатор тела шкипера в config/http.js как это:

bodyParser: {
   fn: require('body-parser').urlencoded,
   options: {extended:true}
 }

но это сделало мой сервер бесполезным, он запустился, но это не так ответить на любой запрос, не знаю почему (даже используя их наш пример со шкипером, что вам просто придется раскомментировать, не получится).

поскольку skipper основан на bodyparser, я изменил индекс модуля skipper.js просто проверить, что происходит.

var URLEncodedBodyParser = connect.urlencoded({extended:true})

но это не сработало, я получаю тот же результат, что и в начале, даже устанавливая body-parser и используя его вместо connect.синтаксический анализатор тела urlencoded не имел никакого эффекта.

Edit 2: As @robertklep заявил, что использует form-data без многостраничных работ, но, конечно, я теряю возможность загружать файлы, что действительно важно и причина, по которой я поместил его в форму примера.

Edit 3: чтобы дополнить принятый ответ, если кому-то это нужно, вот что я сделал:

на config/http.js

middleware: {  
     order: [
      // some middleware
      'bodyParser',
      'qsBodyParser',
      // more middleware
    ],
    qsBodyParser: require('../api/middleware/qsBodyParser')
}

и api/middleware/qsBodyParser

Qs = require('qs');

qsBodyParser = function(req, res, next) {
  if req.is('multipart/form-data'){
   req.body = Qs.parse(req.body);
  }
  return next();
};

module.exports = qsBodyParser;

1 ответов


версия currect skipper зависит от connect@2.25.0, от которой зависит body-parser@1.6.0, который не обрабатывает способ отправки массивов/объектов формы.

ваш пример формы выходит так (используя extended : true):

{
  "entries" : [{
    "content" : "Entry 1 Content..."
  }, {
    "content" : "Entry 2 Content..."
  }]
}

последняя версия (body-parser@1.13.3) работает так, как ожидалось, поэтому вам нужно подключить это к skipper как-то.

редактировать: комментарий похоже, что использование multipart/form-data отключит array (/object?) вообще разбора.

правка #2: вы можете вручную парсить req.body используя qs, который, кажется, принимает объект в качестве аргумента:

var qs  = require('qs');

var obj = qs.parse({
 status: 'published',
 'entries[0][title]': 'Entry 1',
 'entries[0][content]': 'Entry 1 Content...',
 'entries[1][title]': 'Entry 2',
 'entries[1][content]': 'Entry 2 Content...',
});

// obj is now:
// { status: 'published',
//   entries:
//    [ { title: 'Entry 1', content: 'Entry 1 Content...' },
//      { title: 'Entry 2', content: 'Entry 2 Content...' } ] }