为什么我的数组在有22个或更多元素时被转换为对象? (节点)

时间:2018-05-02 22:48:24

标签: html arrays node.js forms express

我提交的表单包含多个共享相同名称的复选框。用节点/快速邮政路线接收它。

这是html:https://pastebin.com/xeQae6GA

如果我尝试打印出长度(req.body.colors.length),那么如果阵列中的元素少于22个,它将起作用。如果它是22或更多,那么它等于undefined。仅打印req.body.colors即可确认。

以下是多次尝试的几个输出,每次添加更多颜色:https://pastebin.com/u6YSRmt6

此数组作为数组存储在数据库中,因此它必须是数组。任何人都知道造成这种情况的原因,或者如何处理它?<​​/ p>

这是完整的节点代码:

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或更多,它将返回undefined。

减少了app.js:https://pastebin.com/wB2bivS0

1 个答案:

答案 0 :(得分:1)

问题是由express-busboy引起的。

检查此程序包的code,它在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
 });

更新

我的拉取请求已合并,express-busboy >= 7.0.0您可以传递arrayLimit参数。