我在我的表单中嵌套信息以匹配我的模型,这大大简化了后端的内容,但我无法找到如何在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()中获得的内容有关。我可以进一步解析这个问题,但如果将来发生变化,那将会是hacky和脆弱的。在任何情况下,这是任何Web应用程序中的常见模式,并且受到许多语言和框架的支持,所以对我来说真的很奇怪,只需简单的sails.js功能就无法获得我需要的东西,所以我猜我我没有做任何应该做的事情,或者我错过了什么。 请指出我正确的方向,如果Sails实际上不支持这种基本的嵌套行为,那我该怎么办?
通过Javascript发送原始内容不是一个选项(除非是不可能的),如本问题的第三个答案所示: Is it possible in Sailsjs to build more complex models 这样做,至少对于基于文本的字段,我得到正确的输出,不确定图像,因为我已经使用rawdata通过postman进行测试。
修改 到目前为止,我已尝试更改config / http.js中的skipper body解析器,如下所示:
bodyParser: {
fn: require('body-parser').urlencoded,
options: {extended:true}
}
但这使得我的服务器无用,它确实启动了,但它没有响应任何请求,不知道为什么(即使使用他们的自己的示例与船长,你只需要取消注释,不起作用)。
由于skipper基于bodyparser,我修改了skipper模块index.js只是为了测试会发生什么。
var URLEncodedBodyParser = connect.urlencoded({extended:true})
但它没有用,我得到的结果与开头相同,甚至安装了body-parser并使用它而不是connect.urlencoded的body解析器没有效果。
编辑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;
答案 0 :(得分:6)
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
,{{3}}似乎接受一个对象作为参数:
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...' } ] }