【问题标题】:How to get arrays/objects sent via form in sails.js (with enctype multipart/form-data)如何获取通过sails.js中的表单发送的数组/对象(使用enctype multipart/form-data)
【发布时间】:2015-11-05 21:11:34
【问题描述】:

我在表单中嵌套信息以匹配我的模型,这大大简化了后端的工作,但我不知道如何在 Sails.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.params.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[]') 会给出正确的行为。我正在检查该 fn 返回的 ._files 属性,并在其中显示我的 2 张图像。 在这里使用括号似乎很奇怪,但就是这样。

我想这与我使用 req.params.all() 得到的结果有关,我可以进一步解析它,但如果将来发生变化,它会变得既笨拙又脆弱。无论如何,这是任何 Web 应用程序中的一种常见模式,并且受到许多语言和框架的支持,所以对我来说真的很奇怪,仅仅使用普通的sails.js 功能似乎不可能得到我需要的东西,所以我猜我'没有做应该做的事情,或者我错过了一些东西。 请指出正确的方向,如果 Sails 实际上不支持这种基本的嵌套行为,那么我应该如何进行?

正如此问题的第三个答案所建议的那样,此处不能选择通过 Javascript 发送原始内容(除非否则不可能): Is it possible in Sailsjs to build more complex models 这样做,至少对于基于文本的字段,我得到了正确的输出,不确定图像,因为我已经通过 postman 使用 rawdata 进行了测试。

编辑: 到目前为止,我已经尝试像这样更改 config/http.js 中的船长正文解析器:

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

但这使我的服务器无用,它确实启动了,但它没有响应任何请求,不知道为什么(即使使用我们的带有船长的示例,您只需取消注释,也不起作用)。

由于 skipper 是基于 bodyparser 的,我修改了 skipper 模块 index.js 只是为了测试会发生什么。

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

但它不起作用,我得到与开始相同的结果,即使安装 body-parser 并使用它而不是 connect.urlencoded 正文解析器也没有效果。

编辑 2: 正如@robertklep 所说,使用没有多部分作品的表单数据,但我当然失去了上传文件的能力,这非常重要,也是我将其放在示例表单中的原因.

编辑 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;

【问题讨论】:

  • body-parser 无法处理 multipart/form-data,这可以解释为什么使用它似乎没有任何改变。
  • 昨晚我在考虑这个问题,今天在没有多部分的情况下进行了检查,确实它解析正确,但我需要它与 multipart/form-data 一起使用

标签: javascript node.js express sails.js


【解决方案1】:

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

编辑this comment 似乎暗示使用multipart/form-data 将完全禁用数组(/object?)解析。

编辑#2:您可以使用qs 手动解析req.body,它似乎接受一个对象作为参数:

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...' } ] }

【讨论】:

  • 在将 multipart/form-data 更改为只是 form-data 之后,令我惊讶的是,即使使用默认的连接正文解析器,但我需要支持以相同的形式上传文件而不依赖于js。我是否应该尝试将qs 作为中间件并尝试从中解析?或者你有什么建议来解决这个问题,因为我基本上和开始在同一个地方?我会更新问题以说明多部分支持非常重要。
  • 确实,这就是我刚刚所做的,我创建了一个中间件并将其添加到 config/http.js 订单中,并使用 qs 重新解析它,我们得到了相同的答案,但你得到了价格(已接受):) 谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-28
  • 1970-01-01
  • 1970-01-01
  • 2011-08-05
  • 1970-01-01
  • 1970-01-01
  • 2014-10-27
相关资源
最近更新 更多