2015-08-13 23 views
7

我在表單中嵌入信息以匹配我的模型,這極大地簡化了後端的操作,但是我可以'找不到如何在Sails.js如何通過sails.js中的表單發送數組/對象

得到數組或對象(或兩者的結合),假設我有一個這樣

注意的一種形式:支持「多/表單數據」是完全需要。

<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()目標文件

{ 
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 這樣做,這樣,至少基於文本字段我得到正確的輸出,不確定與圖像,因爲我已經通過郵遞員測試rawdata。

編輯: 到目前爲止,我已經試過在配置改變船長身體解析器/ http.js這樣的:

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

但是,這使我的服務器沒用,它沒有開始,但它沒沒有迴應任何要求,不知道爲什麼(即使用他們的例子與船長,你只需要取消註釋,不起作用)。

由於skipper基於bodyparser,我修改了skipper模塊index.js來測試發生了什麼。

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

但它沒有工作,我得到了相同的結果開始時,即使安裝體解析器,並用它來代替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; 
+1

'體parser'不處理'多部分/形式data',這將解釋爲什麼使用它似乎沒有改變任何東西。 – robertklep

+0

昨天晚上我在想這個問題,今天沒有多部分檢查,實際上它解析正確,但我需要它使用multipart/form-data – Zagen

回答

6

skipper的正確版本取決於[email protected],這取決於在[email protected],它不處理你發送表單數組/對象的方式。

您的表單例子出來是這樣的(使用extended : true):

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

最新版本([email protected])正常工作,所以你必須把它插入到skipper莫名其妙。

EDITthis comment似乎表明,使用multipart/form-data將禁用陣列(/對象?)解析完全。

EDIT#2:可以使用qsreq.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...' } ] } 
+0

將多部分/表單數據更改爲表單數據後,令我驚訝的是,即使使用默認的連接體解析器,但我需要支持以相同的形式上傳文件而不依賴於js。我應該嘗試掛鉤讓'qs'作爲中間件並嘗試從中解析?或者你有什麼建議來解決這個問題,因爲我基本上和開始時一樣?我會更新這個問題,說明多部分支持是非常重要的。 – Zagen

+0

@Zagen看到我的第二個編輯。 – robertklep

+0

的確,這就是我剛纔所做的,我創建了一箇中間件並將其添加到config/http.js命令中,並使用qs對它進行重新分析,我們得到了相同的答案,但是得到了價格(Accepted):)謝謝。 – Zagen