2016-12-12 2 views
2

У меня есть HTML-форма с массивом флажков (с использованием [] именования). Я должен уметь обрабатывать это с помощью express. Я использую body-parser.Экспресс-манипулятор с обработчиком body-parser по формам

Проблема заключается в том, что непроверенные флажки не представляют значение, и в то же время, тело анализатор кажется, чтобы удалить «дыру» в массивах, просто упаковка значения в массив в порядке убывания индексов, но игнорируя сами индексы. (Обновление: на самом деле это выглядит как qs is the culprit).

Рассмотрим полный пример, который отображает форму и реагирующий с JSON дамп переданных данных:

Установка:

npm install express body-parser 

index.js:

var express = require("express"); 
var site = express(); 

site.use(require("body-parser").urlencoded({extended:true})); 

site.get("/", function (req, res) { 
    res.sendFile(__dirname + "/test.html"); 
}); 

site.post("/form", function (req, res) { 
    res.json(req.body); 
}); 

site.listen(8081); 

тест. html:

<html> 
    <body> 
     <form method="post" action="/form"> 
      <input type="checkbox" name="option[0]" value="1"> 
      <input type="checkbox" name="option[1]" value="1"> 
      <input type="checkbox" name="option[2]" value="1"><br> 
      <input type="text" name="text[0]"><br> 
      <input type="text" name="text[1]"><br> 
      <input type="text" name="text[2]"><br> 
      <button type="submit">Submit</button> 
     </form> 
    </body> 
</html> 

В этом примере, если бы я, чтобы проверить только option[1], я убедиться, что индекс установлен правильно, проверив запрос в Chrome, тело:

option[1]:1 
text[0]: 
text[1]: 
text[2]: 

Но тело-анализатор сворачивает option массив и производит следующее req.body:

{"option":["1"],"text":["","",""]} 

Как вы можете видеть, text имеет все три, но option имеет только один пункт. Точно так же, если бы я, чтобы проверить option[0] и option[2], тело запроса будет выглядеть следующим образом:

option[0]:1 
option[2]:1 
text[0]: 
text[1]: 
text[2]: 

Но это будет разобрано на:

{"option":["1","1"],"text":["","",""]} 

я теряю всю информацию о которой был проверен флажок.

Мой вопрос: Как это сделать? То, что я хочу , чтобы случиться, например:

  • С checkbox[1] Проверила:

    {"option":[null,"1",null],"text":["","",""]} 
    
  • С checkbox[0] и checkbox[2] проверил:

    {"option":["1",null,"1"],"text":["","",""]} 
    

Я не действует Я женился на null и "1", мне просто нужно быть ложным и правдивым.

Кроме того, важно, что я не потерять информацию о том, сколько флажков должно быть в массиве. Например, если бы я дал каждому флажку уникальное значение, я предположил, что могу перевести "option":["0","1"] в массив логических значений, за исключением того, что потерял бы знание о том, что массив имеет размер 3 (при этом в этом случае 3-е значение false) - хотя, я думаю, я мог бы добавить, например скрытый ввод, такой как numberOfCheckboxes=3, но ... этот вид сопоставления громоздкий, и я хотел бы избежать его, если это возможно.

+0

Связанные вопросы отвечал: https://github.com/expressjs/body-parser/issues/211, https://github.com/ljharb/qs/ issues/181 –

ответ

3

Моего подход не требует JavaScript на стороне клиента. Добавить скрытые поля столько, сколько ваших флажков с одинаковыми именами

тела анализатор будет анализировать выбранные элементы в виде массива и строковые другие

Я имел в виду

<input type="hidden" name="option[0]" value="0"> 
<input type="hidden" name="option[1]" value="0"> 
<input type="hidden" name="option[2]" value="0"> 
<input type="checkbox" name="option[0]" value="1"> 
<input type="checkbox" name="option[1]" value="1"> 
<input type="checkbox" name="option[2]" value="1"> 

Если опция [1] установлен, то тело анализатор будет анализировать его как

{option:['0', ['0', '1'], '0']} 

А вот модификатор

req.body.option = req.body.option.map(item => (Array.isArray(item) && item[1]) || null); 

так что теперь тело будет

{option: [null, '1', null]} 
+0

Умный и простой. Мне это нравится. Было бы неплохо, если бы я мог как-то остановить кузов-парсер от рушащихся массивов, но я думаю, что я собираюсь пойти с этим. Благодаря! –

+0

Он всегда будет хранить массивы в том порядке, в котором они находятся на форме, не так ли? Таким образом, никогда не бывает риска, например, '[ '1', '0'] '? Хотя это достаточно легко справиться, я мог бы просто проверить, является ли длина массива 2 в функции «map». –

+1

Я думаю, это зависит от того, где находятся ваши скрытые поля. Если вы поместили скрытые поля сразу после тега открытия формы или непосредственно перед флажками, тогда да @JasonC-порядок будет таким же. –

0

Простейшим решением (не лучшим) является то, что вы можете добавлять скрытые вводные данные с различными идентификаторами, а затем проверять их, когда флажки на странице не отмечены.

<input type="checkbox" name="option[0]" value="1"> 
<input type="checkbox" name="option[1]" value="1"> 
<input type="checkbox" name="option[2]" value="1"> 

<input type="checkbox" class="hidden" name="hiddenOption[0]" value="1"> 
<input type="checkbox" class="hidden" name="hiddenOption[1]" value="1"> 
<input type="checkbox" class="hidden" name="hiddenOption[2]" value="1"> 

И прежде представить:

$('input[name^=option]').each(function() {  
    if(!this.checked) { 
    var name = "input[name=\'hiddenOption" + this.name.replace('option', '') + "\']"; 
    console.log(name); 
    $(name).prop('checked', true); 
    } 
}); 

А потом на его основе вы можете выяснить, какие из них не тикали.

https://plnkr.co/edit/mJCbtgQnQudHGrUzAz3A?p=preview

+0

Итак, если была проверена только опция [option] [1] ', то она будет выставлять опцию [0]: 0, option [1]: 1, option [2]: 0' и' hiddenOption [0]: 1 , hiddenOption [1]: 0, hiddenOption [2]: 1 '? Однако это не сработает. У этой проблемы была бы такая же проблема. Body-parser сворачивает его в 'option: [" 1 "], hiddenOption [" 1 "," 1 "]' и я потерял бы информацию об исходных индексах массива. –