Почему мой массив преобразуется в объект, если в нем 22 или более элементов? (узел) - PullRequest
0 голосов
/ 03 мая 2018

Я отправляю форму с несколькими флажками с одинаковым именем. Получение его с помощью узла / экспресс-маршрута.

вот HTML: https://pastebin.com/xeQae6GA

Если я попытаюсь распечатать длину (req.body.colors.length), она будет работать, если в массиве меньше 22 элементов. Если это 22 или более, то это равно undefined. Распечатка только req.body.colors подтверждает это.

Вот несколько выходов из нескольких попыток, каждый раз добавляя больше цветов: https://pastebin.com/u6YSRmt6

Этот массив хранится в базе данных как массив, поэтому он должен быть массивом. Кто-нибудь знает, что вызывает это или как с этим бороться?


Вот полный код узла:

router.post('/product/:id', function(req, res, next) {

  console.log('COLORS --- count: '+req.body.colors.length);
  console.log(req.body.colors);

});

Заполните форму HTML: https://pastebin.com/0qTnTVFh


код анализатора тела app.js:

var bodyParser = require('body-parser');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

большая часть моего app.js (удален какой-то ненужный / чувствительный код) https://pastebin.com/1mTXiJkx


Я выделил свой роутер и html настолько просто, насколько это возможно, вот они:

test.js

var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {

  res.render('TEST', {
    layout: false,
  })
});

router.post('/', function(req, res, next) {

  console.log('COLORS --- count: '+req.body.colors.length);
  console.log(req.body.colors);

  res.send(''+req.body.colors.length)
});

module.exports = router;

test.hbs

<form method="post" >

  <input id="radio-color-aqua" name="colors" value="aqua" type="checkbox"><label for="radio-color-aqua" style="background-color: #5191bd" title="aqua"></label>

  <input id="radio-color-army" name="colors" value="army" type="checkbox"><label for="radio-color-army" style="background-color: #836652" title="army"></label>

  <input id="radio-color-ash" name="colors" value="ash" type="checkbox"><label for="radio-color-ash" style="background-color: #ecebe9" title="ash"></label>

  <input id="radio-color-asphalt" name="colors" value="asphalt" type="checkbox"><label for="radio-color-asphalt" style="background-color: #505457" title="asphalt"></label>

  <input id="radio-color-athletic-heather" name="colors" value="athletic-heather" type="checkbox"><label for="radio-color-athletic-heather" style="background-color: #a8abb2" title="athletic-heather"></label>

  <input id="radio-color-baby-blue" name="colors" value="baby-blue" type="checkbox"><label for="radio-color-baby-blue" style="background-color: #b6c8db" title="baby-blue"></label>

  <input id="radio-color-berry" name="colors" value="berry" type="checkbox"><label for="radio-color-berry" style="background-color: #c13c7e" title="berry"></label>

  <input id="radio-color-black" name="colors" value="black" type="checkbox"><label for="radio-color-black" style="background-color: #27262b" title="black"></label>

  <input id="radio-color-black-heather" name="colors" value="black-heather" type="checkbox"><label for="radio-color-black-heather" style="background-color: #2A282B" title="black-heather"></label>

  <input id="radio-color-brown" name="colors" value="brown" type="checkbox"><label for="radio-color-brown" style="background-color: #372d2c" title="brown"></label>

  <input id="radio-color-dark-grey-heather" name="colors" value="dark-grey-heather" type="checkbox"><label for="radio-color-dark-grey-heather" style="background-color: #3E3C3D" title="dark-grey-heather"></label>

  <input id="radio-color-deep-heather" name="colors" value="deep-heather" type="checkbox"><label for="radio-color-deep-heather" style="background-color: #9B9A9F" title="deep-heather"></label>

  <input id="radio-color-forest" name="colors" value="forest" type="checkbox"><label for="radio-color-forest" style="background-color: #1F4A2E" title="forest"></label>

  <input id="radio-color-gold" name="colors" value="gold" type="checkbox"><label for="radio-color-gold" style="background-color: #f8a933" title="gold"></label>

  <input id="radio-color-heather-blue" name="colors" value="heather-blue" type="checkbox"><label for="radio-color-heather-blue" style="background-color: #86A9C9" title="heather-blue"></label>

  <input id="radio-color-heather-deep-teal" name="colors" value="heather-deep-teal" type="checkbox"><label for="radio-color-heather-deep-teal" style="background-color: #426275" title="heather-deep-teal"></label>

  <input id="radio-color-heather-forest" name="colors" value="heather-forest" type="checkbox"><label for="radio-color-heather-forest" style="background-color: #4F5549" title="heather-forest"></label>

  <input id="radio-color-heather-midnight-navy" name="colors" value="heather-midnight-navy" type="checkbox"><label for="radio-color-heather-midnight-navy" style="background-color: #35353F" title="heather-midnight-navy"></label>

  <input id="radio-color-heather-mint" name="colors" value="heather-mint" type="checkbox"><label for="radio-color-heather-mint" style="background-color: #72D3B4" title="heather-mint"></label>

  <input id="radio-color-heather-orange" name="colors" value="heather-orange" type="checkbox"><label for="radio-color-heather-orange" style="background-color: #D96E51" title="heather-orange"></label>

  <input id="radio-color-heather-raspberry" name="colors" value="heather-raspberry" type="checkbox"><label for="radio-color-heather-raspberry" style="background-color: #FC667D" title="heather-raspberry"></label>

  <input id="radio-color-heather-true-royal" name="colors" value="heather-true-royal" type="checkbox"><label for="radio-color-heather-true-royal" style="background-color: #5F98E6" title="heather-true-royal"></label>

  <input id="radio-color-kelly" name="colors" value="kelly" type="checkbox"><label for="radio-color-kelly" style="background-color: #016d56" title="kelly"></label>

  <input id="radio-color-leaf" name="colors" value="leaf" type="checkbox"><label for="radio-color-leaf" style="background-color: #548655" title="leaf"></label>

  <input id="radio-color-light-blue" name="colors" value="light-blue" type="checkbox"><label for="radio-color-light-blue" style="background-color: #94afca" title="light-blue"></label>

  <input id="radio-color-navy" name="colors" value="navy" type="checkbox"><label for="radio-color-navy" style="background-color: #37384a" title="navy"></label>

  <input id="radio-color-ocean-blue" name="colors" value="ocean-blue" type="checkbox"><label for="radio-color-ocean-blue" style="background-color: #619dc1" title="ocean-blue"></label>

  <input id="radio-color-olive" name="colors" value="olive" type="checkbox"><label for="radio-color-olive" style="background-color: #434c31" title="olive"></label>

  <input id="radio-color-pink" name="colors" value="pink" type="checkbox"><label for="radio-color-pink" style="background-color: #fcd1db" title="pink"></label>

  <input id="radio-color-red" name="colors" value="red" type="checkbox"><label for="radio-color-red" style="background-color: #a02331" title="red"></label>

  <input id="radio-color-silver" name="colors" value="silver" type="checkbox"><label for="radio-color-silver" style="background-color: #b8bcbf" title="silver"></label>

  <input id="radio-color-soft-cream" name="colors" value="soft-cream" type="checkbox"><label for="radio-color-soft-cream" style="background-color: #d3c4ad" title="soft-cream"></label>

  <input id="radio-color-steel-blue" name="colors" value="steel-blue" type="checkbox"><label for="radio-color-steel-blue" style="background-color: #4d657d" title="steel-blue"></label>

  <input id="radio-color-true-royal" name="colors" value="true-royal" type="checkbox"><label for="radio-color-true-royal" style="background-color: #18498c" title="true-royal"></label>

  <input id="radio-color-white" name="colors" value="white" type="checkbox"><label for="radio-color-white" style="background-color: #e2e3de" title="white"></label>

  <input id="radio-color-yellow" name="colors" value="yellow" type="checkbox"><label for="radio-color-yellow" style="background-color: #fbf271" title="yellow"></label>


  <input type="submit" />
</form>

Похоже, ошибка та же. Установите флажки 18, 19, 20, 21, это число вернется. Отметьте 22 или больше, и он вернет неопределенное.

вырежьте app.js: https://pastebin.com/wB2bivS0

1 Ответ

0 голосов
/ 03 мая 2018

Проблема вызвана express-busboy.

Проверяя код этого пакета, он использует синтаксический анализатор строки запроса на req.body

 req.busboy.on('finish', () => {
    // This next line is the culprit
    req.body = qs.parse(qs.stringify(req.body));
    if (restrictMultiple) {
        [req.body, req.files].forEach(fixDups);
    }
    bbDone = true;
    finish();
});

В документах qs мы видим следующее:

qs также ограничит указание индексов в массиве максимальным индексом из 20. Любые члены массива с индексом больше 20 будут вместо быть преобразован в объект с индексом в качестве ключа Этот предел можно изменить, передав опцию arrayLimit

Вот почему все работает до 20 пунктов

Если вы удалите часть «busboy», код будет работать должным образом:

// Remove this
bb.extend(app, {
    upload: true,
    path: './temp',
    allowedPath: /./
});

На мой взгляд, у вас есть два варианта

1) Используйте multer для загрузки файлов вместо busboy

2) Вилка express-busboy и добавление { arrayLimit: options.arrayLimit }

Примечание: Чтобы избежать возможной атаки DOS, вы должны установить разумный предел:)

req.busboy.on('finish', () => {
    req.body = qs.parse(qs.stringify(req.body), { arrayLimit: options.arrayLimit });
    if (restrictMultiple) {
        [req.body, req.files].forEach(fixDups);
    }
    bbDone = true;
    finish();
});

А теперь назовите это так:

 bb.extend(app, {
    upload: true,
    path: './temp',
    allowedPath: /./,
    arrayLimit: 50
 });

UPDATE

Мой запрос извлечения объединен, и из express-busboy >= 7.0.0 вы можете передать параметр arrayLimit.


...