0

I have made a form using 3rd party plugins (multiple and wmd-editor). My HTML is :

<form id="form" class="form" method="post" action="/questions">
    <div id="title" class="form__title">
        <div id="question_title">Title</div>
        <input id="input_element1" class="input_element" type="text" placeholder="What's your programming question? Be specific." name="title">
    </div>
    <div class="text-area">
        <div id="wmd-button-bar"></div>
        <br/>
        <textarea id="wmd-input" name="text"></textarea>
        <div id="wmd-preview"></div>
        <br/>
    </div>
    <div class="inputtags form__tags">
        <select id="options" multiple="multiple" name="tags">
        </select>
        <div class="inputtags__element"></div>
        <div class="inputtags__errors"></div>
        <br>
        <div id="inputtags__post">
            <button class="btn" id="btn-submit">
                Post Your Question
            </button>
            <button class="btn" id="btn-discard">
                Discard
            </button>
        </div>
    </div>
</form>

I am putting tags in the options select using the javascript and the javaScript code is:

var index = -1;
var htmlStr = tags.reduce(function(a,b){
    index++;
    return a + "<option value="+(index+1)+" name="+b+">"+b+"</option>"; 
},'');
$("#options").html(htmlStr);

I am fetching these in the routes file of my node.js (express framework) as :

router.post('/questions', function(req,res){
    var question = req.body;
    console.log(question);
    Question.createQuestion(question);
    res.redirect('/');
});

Here req.body should give me the name of DOMs as suggested in expressjs Documentation. I have given name to my option in my javascript code but still when the data is pushed to the database, the req.body return me following:

{
    title: 'title',
    text: '<p>Body</p>',
    tags: [ '1', '2', '3', '4', '5', '6', '7', '8' ]
}

My code in app.js:

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');

What I am doing wrong?

Thomas Bormans
  • 5,156
  • 6
  • 34
  • 51
Ajay Gaur
  • 5,140
  • 6
  • 38
  • 60

2 Answers2

0

Since you are using numerical values <option value="+(index+1)+" this is what you get.

For ["foo","bar baz"] your code produces: <option value=1 name=foo>foo</option><option value=2 name=bar baz>bar baz</option>

This is very bad html code and will send 1 and 2 as values.

If you want to use the tag strings as values change it to

return a + "<option value=\"" + b + "\">" + b + "</option>";

to get <option value="foo">foo</option><option value="bar baz">bar baz</option> and ["foo", "bar baz"] as req.body.tags on the server.

I removed the name property from option because it does not do anyhing (you have already defined a name for the select tag).

You should only do this if you have defined the tags, never insert untrusted user input as html code!

Anatol - user3173842
  • 1,385
  • 1
  • 12
  • 16
  • have you refreshed the page? check what your browser is posting using dev tools: http://stackoverflow.com/a/9163566/3173842 if your browser posts tags as [1,2,3... this is a client side problem. – Anatol - user3173842 Mar 09 '16 at 08:01
0

This is from a part from express boilerplate generated by express-generator

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.text());
//rest of the code

and in user router file

var express = require('express');
var router = express.Router();

router.post('/questions', function(req, res) {
    res.status(200).json(req.body);
});

If you do a POST call to /users/questions using POSTMAN and pass your data as JSON you will get it because I just spit it as response. Do not forget to set Content-Type: application/json in request header. For file upload you can try multer or busboy

for more on body-parser please check body-parser

Nur Rony
  • 7,823
  • 7
  • 38
  • 45