I have a small express app, which consists of the server, some views and a router. Here's my server.js:
const express = require('express');
const helmet = require('helmet');
const app = express();
app.use(helmet.contentSecurityPolicy({ directives: { defaultSrc: ["'self'"], scriptSrc: ["'self'", 'maxcdn.bootstrapcdn.com', 'ajax.googleapis.com'], styleSrc: ["'self'", 'maxcdn.bootstrapcdn.com'], imgSrc: ["'self'", 'image.tmdb.org'] } }));
const path = require('path');
const bp = require('body-parser');
const routes = require('./routes/index');
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.set(express.json());
app.set(bp.urlencoded({extended: false}));
app.set(bp.json())
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.listen(3000, () => {
console.log('Servidor online');
})
Here's my router.js:
const express = require('express');
const request = require('request');
const router = express.Router();
router.post('/search', (req, res, next) => {
console.log(req.body);
res.send('sanity check');
});
module.exports = router;
And here's the view (it's a form inside a navbar):
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/">The New IMDB</a>
</div>
<ul class="nav navbar-nav">
<li>Login</li>
<li>Favorites</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
<form action="/search?source=hp" method="POST" id="search-form" class="form-inline">
<div class="form-group">
<select name="categ" class="form-control" id="cat">
<option value="movie">Movie Title</option>
<option value="person">Actor</option>
</select>
</div>
<input type="text" id="movie" placeholder="Search" name="movieSearchq" />
<input type="submit" class="btn btn-primary" />
</form>
</li>
</ul>
</div>
</nav>
I've searched previous questions and found out that bodyParser was not being shipped with express anymore, so i've installed it, but it still does not create the body object inside the req. Am i missing something here?
You've incorrectly setup the body-parser to parse form-data since you're using app.set (use this only to set apply express settings).
Instead you need to setup middlewares using app.use:
app.use(bp.urlencoded({extended: false}));
app.use(bp.json());
Related
editUser.js which is loading the data correctly, however when clicking on update I am getting (404 not found error), not able to understand why update route is not getting invoked. It is working for /, createUser, editUser/:id (for loading user data).
editUser.js
<div class="container">
All Users
<form class="col g-3 mt-3"" method="post" action="/update/<%= user.id %>">
<div class="col-md-6">
<label for="inputFirstName" class="form-label">First Name:</label>
<input type="text" class="form-control" value="<%= user.first_name %>" name="first_name" id="first_name">
</div>
<div class="col-md-6">
<label for="inputLastName" class="form-label">Last Name</label>
<input type="text" class="form-control" value=<%= user.last_name%> name="last_name" id="last_name">
</div>
<div class="col-md-6">
<label for="inputEmail" class="form-label">Email</label>
<input type="email" class="form-control" value=<%= user.email%> name="email" id="email">
</div>
<div class="col-md-6 mt-3">
<button type="submit" class="btn btn-primary">Update</button>
</div>
</form>
</div>
routes/index.js
var express = require('express');
var router = express.Router();
var {allUsers, createUser, saveUser, editUser, updateUser} = require('../controllers/userController')
/* GET users listing. */
//Commenting default function
router.get('/', allUsers)
router.get('/createUser', createUser)
router.post('/createUser', saveUser)
router.get('/editUser/:id', editUser)
router.post('/updateUser/:id', updateUser)
module.exports = router;
controllers/userController.js
const User = require('../models/userModel')
const updateUser = async (req, res) => {
console.log('Updating User')
const userId = req.params.id
const userData = req.body
const selector = {where: {id:userId}}
await User.update(userData, selector).catch(error => console.log(error))
res.redirect('/')
}
module.exports = { allUsers,createUser,saveUser,editUser,updateUser }
app.js
//Imports
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var expressLayouts = require('express-ejs-layouts')
const routes = require('./routes');
//DOTENV for storing sensitive data
require('dotenv').config({path:'./bin/.env'})
var app = express();
// View engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs'); //Key, Value
app.set('layout','layouts/layout')
//Middleware between requet and response
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(expressLayouts)
//Use Router
app.use('/',routes)
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
//error handler first parameter is "err"
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Form action should be action="/updateUser/<%= user.id %>
IF i am not logged in and make "GET" request to "/sell" i am redirected to "/user/login" which is working accordingly.But if i am logged in and i make GET request to "/sell" i am always redirected to
"/" i.e. homepage instead of "/sell" page.so what should i do to only access "/sell" page if i am logged in?.Here are the code snippets you may probably need. Please let me know if u need anything else. Thank you in advance.
/routes/sell.js
const express = require('express');
const router = express.Router();
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({extended:false});
const Product = require('../models/product');
router.get('/sell', isLoggedIn, (req, res, next) => {
res.render('sell',{title: 'Home|Sell', success: req.session.success, errors: req.session.errors, csrfToken: req.csrfToken()});
req.session.success = null;
req.session.errors = null;
})
router.post('/book_upload', isLoggedIn, (req, res, next) => {
req.check('name')
.isLength({min:3}).withMessage('Name must be of 3 characters long.')
.matches(/^[A-Za-z\s]+$/).withMessage('Name must be alphabetic.');
req.check('phone')
.isLength({min:10,max:10}).withMessage('Phone number must be of 10 digits.');
req.check('book_name')
.isLength({min:3}).withMessage('Book Name must be of 3 characters long.')
.matches(/^[A-Za-z\s]+$/).withMessage('Book Name must be alphabetic.');
req.check('book_price')
.isNumeric().withMessage('Price must be numeric.');
req.check('description')
.isLength({min:3}).withMessage('Description must be of 3 characters long.')
.matches(/^[<A-Za-z0-9></A-Za-z0-9>\s]+$/).withMessage('Please write appropriate description.')
req.check('faculty')
.isLength({min:3}).withMessage('Faculty must be of 3 characters long.')
.matches(/^[A-Za-z\s]+$/).withMessage('Faculty must be alphabetic.')
var errors = req.validationErrors();
if (errors){
req.session.errors = errors;
req.session.success = false;
} else {
req.session.success = true;
var item = {
name: req.body.name,
phone: req.body.phone,
book_name: req.body.phone,
book_price: req.body.price,
description: req.body.description,
faculty: req.body.faculty
};
var data = new Product(item);
data.save();
}
res.redirect('/sell');
})
function isLoggedIn (req, res, next){
if (req.isAuthenticated()){
return next();
}
req.flash('error', 'Please Login to Continue')
res.redirect('/user/login');
}
module.exports = router;
and app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var expressHbs = require('express-handlebars');
var mongoose = require('mongoose');
var session = require('express-session');
var passport = require('passport');
var flash = require('connect-flash');
var validator = require('express-validator');
// var MongoStore = require('connect-mongo')(session);
mongoose.connect('mongodb+srv://username:password#firstdatabase-ytrfr.mongodb.net/test?retryWrites=true&w=majority',{
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(()=>console.log('Connected to the database'))
.catch(err=> console.log('could not connect.',err.message))
// passport
require('./config/passport');
var indexRouter = require('./routes/index');
var userRouter = require('./routes/user');
var sellRouter = require('./routes/sell');
var app = express();
// view engine setup
app.engine('.hbs', expressHbs({ defaultLayout: 'layout', extname: '.hbs'}))
app.set('view engine', '.hbs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(validator());
app.use(session({
secret: 'blahblah',
resave: false,
saveUninitialized: false,
}))
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static(path.join(__dirname, 'public')));
app.use((req, res, next) => {
res.locals.login = req.isAuthenticated();
res.locals.session = req.session;
next();
})
app.use('/', indexRouter);
app.use('/', userRouter);
app.use('/', sellRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
and sell.hbs
<section class="my_account_area pt--80 pb--55 bg--white">
<div class="container">
<div class="row">
<div class="col-lg-6 col-12">
<div class="my__account__wrapper">
{{# if success}}
<section class="success">
<h2>Form submitted!</h2>
</section>
{{else}}
{{# if errors}}
<div class="alert alert-danger">
<section class="errors">
<ul>
{{# each errors}}
<li>{{ this.msg }}</li>
{{/each}}
</ul>
</section>
</div>
{{/if}}
<h3 class="account__title">Fill Up the Information of Book</h3>
<form action="/book_upload" method="post">
<div class="account__form">
<div class="input__box">
<label>Your Name <span>*</span></label>
<input type="text" id="name" name="name">
</div>
<div class="input__box">
<label>Phone No. <span>*</span></label>
<input type="number" id="phone" name="phone">
</div>
<div class="input__box">
<label>Name of book <span>*</span></label>
<input type="text" id="book_name" name="book_name">
</div>
<div class="input__box">
<label>Price of Book<span>*</span></label>
<input type="number" id="book_price" name="book_price">
</div>
<div class="input__box">
<label>Description of Book<span>*</span></label>
<input type="text" id="description" name="description" placeholder="e.g. To study in 1st year 1st part">
</div>
<div class="input__box">
<label>Faculty<span>*</span></label>
<input type="text" id="faculty" name="faculty">
</div>
<input type="hidden" name="_csrf" value="{{ csrfToken }}">
<div class="form__btn">
<button type="submit">Upload</button>
</div>
</div>
</form>
</div>
{{/if}}
</div>
</div>
</div>
</section>
Middleware functions are executed sequentially, therefore the order of middleware inclusion is important.
Hence, change the order of
app.use('/', indexRouter);
app.use('/', userRouter);
app.use('/', sellRouter);
to
app.use('/', sellRouter);
app.use('/', indexRouter);
app.use('/', userRouter);
It will work.
Im using express, node, bodyParser to pull information from a contact form and post it to the terminal. When I run the code and access my demo site through LocalHost:3000, upon submitting, my input items are not showing up in the terminal.
I've tried changing the form attributes action="send" action="/send" action="/"
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const exphbs = require('express-handlebars');
const nodemailer = require('nodemailer');
const app = express();
// View engine setup
app.engine('handlebars', exphbs());
app.set('view engine', 'handlebars');
// Static folder
app.use('/public', express.static(path.join(__dirname, 'public')));
/ Body Parser Middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.get('/', (req, res) => {
res.render('contact', { layout: false });
});
app.post('/send', (req, res) => {
console.log(res.body);
});
//Form HTML code
<form action="send" method="POST">
<input name="name" type="text" id="name" placeholder="NAME: First & Last">
<input name="email" type="text" id="email" placeholder="EMAIL:">
<textarea name="text" id="text" cols="30" rows="10" placeholder="QUESTION OR INQUIRY:"></textarea>
<br>
<button type="submit">Submit</button>
</form>
Have you tried console logging the req instead of the res for the app.post?
If you are doing console.log(req.body) then this should output a long json object. If this is not happening, then you are not hitting the url.
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const exphbs = require('express-handlebars');
const nodemailer = require('nodemailer');
const app = express();
// View engine setup
app.engine('handlebars', exphbs());
app.set('view engine', 'handlebars');
// Static folder
app.use('/public', express.static(path.join(__dirname, 'public')));
// Body Parser Middleware
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
app.get('/', (req, res) => {
res.render('contact', { layout: false });
});
app.post('/send', (req, res) => {
console.log(res.body);
});
The problem is in your html code. I have made some changes, Try this.
//Form HTML code
<form action="http://localhost:9000/send" method="POST">
<input name="name" type="text" id="name" placeholder="NAME: First & Last">
<input name="email" type="text" id="email" placeholder="EMAIL:">
<textarea name="text" id="text" cols="30" rows="10" placeholder="QUESTION OR INQUIRY:"></textarea>
<br>
<button type="submit">Submit</button>
</form>
I have two ejs in my views folder
I have created very simple ejs to see if I can send the variable from one ejs to another ejs.
a.ejs in veiws file
<form name="input" action="\home" method="post">
<input type='checkbox' checked>Cheese
<input type="submit" value="Submit" href="validation.ejs">
</form>
b.ejs has
<h1><% post my variable here%></h1>
in my node js this is what i did
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.set('view engine', 'ejs');
app.get('/', (req, res) => {
res.render('index', { title: 'EJS Demo' });
});
app.post('/', (req, res) => {
const a = req.body.a;
res.get('index2',a);
});
app.listen(3000, () => {
console.log('Listening....');
});
i think the post has to do something in here...
I think you need to submit a value from form1 in page1 and pass that variable to page2
if thats the case you can do like this
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.set('view engine', 'ejs');
// send the page1 to the user
app.get('/', (req, res) => {
res.render('page1', { title: 'EJS Demo' });
});
//capture the submit from the user and then send another page
//to the user
app.post('/submitForm', (req, res) => {
const a = req.body.valueFromA;
res.render('page2',a);
});
app.listen(3000, () => {
console.log('Listening....');
});
<form name="input" action="\home" method="post">
<input type='checkbox' checked>Cheese
<input type="submit" value="Submit" href="validation.ejs">
</form>
<!-- page1 form1 -->
<html>
<head>
<title> <& title &> </title>
</head>
<form action='/submitForm' method='post'>
<input type='text' value='' name='valueFromA' />
<input type='submit' />
</form>
</html>
<!-- page2 ejs -->
<html>
<body>
<p> <% value %> </p>
</body>
</html>
b.ejs has
<h1><% post my variable here%></h1>
in my node js this is what i did const
I am creating a multiplayer game with login system. However, there is one error, which I don't know how to solve. When I run my app I get the following error:
net::ERR_CONNECTION_CLOSED.
Here is my app.js
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var exphbs = require('express-handlebars');
var expressValidator = require('express-validator');
var flash = require('connect-flash');
var session = require('express-session');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var mongo = require('mongodb');
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/loginapp');
var db = mongoose.connection;
var routes = require('./routes/index');
var users = require('./routes/users');
// Init App
var app = express();
var http = require('http');
var server = require("http").Server(app);
var io = require("socket.io")(server);
// View Engine
app.set('views', path.join(__dirname, 'views'));
app.engine('handlebars', exphbs({defaultLayout:'layout'}));
app.set('view engine', 'handlebars');
// BodyParser Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
// Set Static Folder
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(__dirname + 'views'));
// Express Session
app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true
}));
// Passport init
app.use(passport.initialize());
app.use(passport.session());
// Express Validator
app.use(expressValidator({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param : formParam,
msg : msg,
value : value
};
}
}));
// Connect Flash
app.use(flash());
// Global Vars
app.use(function (req, res, next) {
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
res.locals.user = req.user || null;
next();
});
app.use('/', routes);
app.use('/users', users);
app.set('port', (process.env.PORT || 3000));
io.on('connection', function(socket)
{
console.log('New connection attempt');
});
server.listen(app.get('port'), function(){
console.log('Server started on port '+app.get('port'));
});
my layout.handlebar
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='/bootstrap/css/bootstrap1.css' />
<link rel = "stylesheet" href="/css/style.css" />
<title>IKTSL</title>
<style>
#question_options div button:nth-child(1){
visibility: visible;
}
</style>
<script src='/socket.io/socket.io.js'></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
</head>
<body>
<script>
var socket = io.connect('https://localhost:3000');
</script>
<div class="container">
<div class="row">
<div class="col-lg-12">
{{#if success_msg}}
<div class="alert alert-success">{{success_msg}}</div>
{{/if}}
{{#if error_msg}}
<div class="alert alert-danger">{{error_msg}}</div>
{{/if}}
{{#if error}}
<div class="alert alert-danger">{{error}}</div>
{{/if}}
</div>
</div>
</div> <!-- /container -->
<div class='container-fluid'>
<div class='row'>
<div class='span12'>
<br>
<br>
<h1>I Know This Song Lyrics!</h1>
<br>
</div>
</div>
<br>
<br>
<div class='row'>
<div class='span4'>
<div class='well'>
<div class="header clearfix">
<nav>
<ul class="nav nav-pills pull-right">
{{#if user}}
<li role="presentation">Dashboard</li>
<li role="presentation">Logout</li>
{{else}}
<li role="presentation">Login</li>
<li role="presentation">Register</li>
{{/if}}
</ul>
</nav>
<h3 class="text-muted">Log in</h3>
</div>
</div>
</div>
<div class='span8'>
<div class='hero-unit'>
{{{body}}}
</div>
</div>
<div class='span5'>
<div class='users'>
<h3>Players</h3>
<div class="connectedUsers"></div>
</div>
</div>
</div>
</body>
</html>
I am just trying to console log "New connection attempt" when I starts working but that doesn't work.
I'll be grateful for any help. Thanks a lot in advance.
Firstly, I believe you can change to this (remove the additional require of http and set io to listen to server):
// Init App
var app = express();
var server = require("http").Server(app);
var io = require("socket.io").listen(server);
If your client-side is running on a different port than your server, you should change your import as well, I think. Otherwise, that piece might be fine. I don't think you need the .connect on io in var socket = io.connect(); Mine is working without it, anyway.
<script src='http://localhost:3000/socket.io/socket.io.js'></script>