How to catch 404 error in Express/Nodejs? [duplicate] - javascript

This question already has an answer here:
Nodejs handle unsupported URLs and request types
(1 answer)
Closed 5 years ago.
var express = require('express');
var path = require('path');
var app = express();
app.use(express.static(path.join(__dirname, 'public')));
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
I confused when catch 404 error and when not?
I want achieve the goal when input correct request path will not catch 404 error,otherwise bad request path will.

In your routes folder(if you are using express-gen) or anywhere else create a node module which uses express.router() as follows
var express = require('express');
var bodyParser = require('body-parser');
var dishRouter = express.Router();
dishRouter.use(bodyParser.json());
Then handle your requests, example:
dishRouter.route('/')
.get(function(req, res, next) {
res.end('Will send all the dishes to you!');
})
.post(function(req, res, next) {
res.end('Will add the dish: ' + req.body.name + ' with details: ' + req.body.description);
});
And use this in ur app.js or the main file which you run:
var express = require('express');
var path = require('path');
var dishRouter=require('./routes/dishRouter');
var app = express();
app.use(express.static(path.join(__dirname, 'public')));
app.use('/dishes',dishRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
res.redirect('/fail');
next(err);
});
So what this will do is that, it will handle the get and post requests from client for URI /dishes and for others, it will throw an error 404 and send to /fail path.

Remember the express use() is executed for all request, so what is happening is your 404 status is attached to all request within your application. Use it in the callback which checks whether the input is correct or not, for example if its an HTTP express post request:
// This is just an example, please note
app.post('/signin', function(req, res) {
if(!user.passwordCheck(req.body.password) {
res.status(404).send({
message: 'Incorrect input'
});
} else res.redirect('/success');
}
I hope this helps.

Related

Nodejs how response locals on each get view on app.use

I am trying to handle simple user information through cookies, this information is visible in my layout through res.render, but I saw it very tedious, since it will always be simple information and I would have to be doing it in each .get (), then in app.js I did this:
app.js
app.use(function(req,res, next){
var cookies = req.cookies;
if(!cookies.UserData){
console.log('cookies no exists');
}
else{
console.log('cookies');
res.locals.user = cookies.UserData;
next();
}
});
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
layout.ejs
<%- user.username %>
but "user" was not defined, but in my error.ejs When a 404 was generated, I put "<%- user.username %>" it in and it worked.
but it only works on 404 catches and not in general, what am I doing wrong? how I do this?
how I solved it
In my Router-level middleware:
var express = require('express');
var router = express.Router();
router.use(function(req,res, next){
var cookies = req.cookies;
if(!cookies.UserData){
console.log('cookies no exist');
}
else{
console.log('cookies');
res.locals.user = cookies.UserData;
next();
}
});
I put it first in the router-level middleware, above all the other http methods

Node JS - "Could not get any response" On Insert Data to Database

I'm trying to Insert some data to my database(mysql) with nodejs and I already did make some code but in postman it displays Could not get any response even though I know that I followed properly some tutorials that I watched.
Here's my code
SendOrder.js (models)
var db=require('../dbconnection');
var Task = {
addTask:function(Task,callback){
return db.query("Insert into orders ( order_id, order_no, tbl_id, menu_id, \
order_quantity, order_discount, order_type, \
order_amount, menu_name, menu_price ) values(?,?,?,?,?,?,?,?,?,?)",
[
Task.order_id, Task.order_no, Task.tbl_id, Task.menu_id,
Task.order_quantity, Task.order_discount, Task.order_type,
Task.order_amount, Task.menu_name, Task.menu_price
], callback);
},
}
module.exports=Task;
SendOrder.js (router)
var express = require('express');
var router = express.Router();
var Task = require('../models/SendOrder');
router.post('Send/', function(req, res, next){
Task.addTask(req.body,function(err,count){
console.log(req.body);
if(err)
{
res.json(err);
}
else{
res.json(req.body);
}
});
});
module.exports = router;
EDIT:
dbconnection.js
var mysql=require('mysql');
var connection=mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'opob',
});
module.exports=connection;
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 mysql = require('mysql');
var connection = require('express-myconnection')
var SendOrder = require('./routes/SendOrder'); // SendOrder
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
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('/SendOrder', SendOrder); // SendOrder
// 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;
Go to Setting in Postman
Off the SSL certificate verification in General tab: (Second option under Request)
Off the Global Proxy Configuration and Use System Proxy in Proxy tab:
If both not work, try below code:
if(err)
{
return res.status(500).json(err);
}
else{
return res.status(200).json(req.body);
}
Hope, this may help you!
=========== EDITED ==============
Looking at your app.js file. It seems you need to use body-parser package to parse the JSON data from request.
npm install body-parser --save
body-parser extract the entire body portion of an incoming request stream and exposes it on req.body.
From whatever you have shared here are the following possibilities:
Your IP/PORT that you are trying to hit is wrong. Please cross verify them again.
The IP that you are trying to hit is not accessible from the machine where postman is installed (I added this possibility as you are using IP instead of localhost)
The third possibility would be server crashing when you hit the Send/ API. If the problem is with your code, most probably this is the reason. In this case, you can check the server console to find crash logs and stack-trace.
As #Hardik has mentioned in the comments is not a wrong URL as that would return 404.

How to access the post body in express route?

I am learning how to build a web app using express, node, and angular. I have a post request from angular, and I can successfully send that to the router in login.js:
var user = {username: $scope.userName, password: $scope.password};
$scope.login = function() {
console.log('attempting to log in,,');
console.log("The useranem" + $scope.userName + " " + $scope.password + " " + user);
$http.post('/userLogin', user).then(successCallback, errorCallback);
};
index.js
var express = require('express');
var router = express.Router();
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'xxxxx',
database : 'xxxxx'
});
connection.connect();
router.post('/userLogin', function(req, res, next){
console.log('the user name is ' + req.body);
});
module.exports = router;
From the image, I can see that I was able to print out the body of the post request as objects. Is this because I don't have body parser in index.js.
I already installed body parser in app.js,
1) do I have to require app.js in index.js to use the body parser?
2)And once I am able to parse the body, how do I access the varaibles in the body. Would it be req.username and req.password?
3) This question is not as related, but in my app.js I have app.use('/', login). How do i determine what the path should be? Should it be the same as the express router such as /userLogin?
This is my 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 mysql = require('mysql');
var routes = require('./routes/index');
var register = require('./routes/register');
var users = require('./routes/users');
var login = require('./routes/login');
var app = express();
//establish database connection
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'xxxxx',
database : 'xxxxx'
});
connection.connect();
// 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(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/', login);
//add route for registering account
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
Note: most of the stuff in app.js was created using express generator.
Looks like you need to access the data from req.body that you want. So if the object you want to access from that is user from the json object you'd need to access req.body.user
You are trying to concatenate an object with a string. This forces the standard output to call the method toString() from the object which results in [object Object] if it's not overridden with a custom implementation.
To see the whole object, you can use: console.log(req.body);
then you will be able to see the object.

Route not found in node and express

I am currently learning the MEAN stack by working my way through this tutorial. I have set up the node server and gotten mongodb successfully running however when i go to test the database via:
curl --data 'title=test&link=http://test.com' http://localhost:3000/posts
it gives me a 404 error. How ever if i just run curl on the address it sends back an empty container.
Currently my code looks like the following:
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 app = express();
var users = require('./routes/users');
var mongoose = require('mongoose');
require('./models/Posts');
require('./models/Comments');
mongoose.connect('mongodb://localhost/Posts');
var routes = require('./routes/index');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
...
module.exports = app;
index.js
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var Post = mongoose.model('Post');
var Comment = mongoose.model('Comment');
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', {
title: 'Express'
});
});
router.get('/Posts', function(req, res, next) {
Post.find(function(err, posts) {
if (err) {
return next(err);
}
res.json(posts);
});
});
router.post('/Comments', function(req, res, next) {
var post = new Post(req.body);
post.save(function(err, post) {
if (err) {
return next(err);
}
res.json(post);
});
});
module.exports = router;
I feel like I have a fairly good grasp of javascript however i am stumped with why this isnt working. Thanks for the help, this is the first problem ive been completely stumped with

Another express.js req.session not storing data

I have been staring at the same SO questions/answers for too long.
I am trying to set my user ID in a req.session variable
here is my app.js stack
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, cors = require('cors')
, mongoose = require('mongoose')
, User = require('./user-model')
, path = require('path')
, mysql = require('mysql');
app = express()
/**
* Middleware.
*/
app.use(cors());
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'supercalafragalistic' }));
app.locals.pretty = true;
app.use(express.static(path.join(__dirname, 'public')));
app.set('view engine', 'jade');
...
app.get('/someRoute', routes.someRoute)
I have moved the app.router from top to bottom. Currently it is implied (I just deleted it as I stripped my code looking for error). I have exported app, included app in routes (also erased) . I added middleware. I am lost.....
here is my route stack
//routes/index.js
//requires
var User = require('../user-model')
,qs = require('querystring')
,http = require('http')
,mysql = require('mysql')
,connection = mysql.createConnection({
edited
});
/**
* Set up application.
*/
connection.connect(function(err){
if(err) console.log('failed to connect to mysql because'+ err);
else console.log('connected to mysql');
})
I save the id in the login route:
//login processing route
exports.logIn = function(req, res, next){
console.log('log in request from '+req.body.name);
User.findOne({name:req.body.name}, function(err, user, next){
if(err) return next(err);
if(!user) return res.end();
//check password
user.comparePassword(req.body.password, function(err, isMatch){
if(err) res.send('failed to find user');
console.log(""+isMatch);
if(isMatch){
console.log(user._id.toString()+' user loggd in');
//set session cookie
req.session.loggedIn = user._id.toString();
console.log('req.session.loggedIn set to :'+req.session.loggedIn );
res.send(user);
}else {
res.send('User not found try again');
}
});
});
However, in all other routes the variable is undefined:
// clock status
exports.clockStatus = function(req, res, next){
var user = req.session.loggedIn;
console.log('Status route, userID: '+user);
if(user){
I found the answer in "Cannot access req.session variables in Express/NodeJS" but the last part trails off:
In your case, you have assigned req.session.user = user; only in
/login request. It will not be available for further requests(/auth).
You have to get user information in /auth request too by session id.
(Or) Better you can use passport for authentication.
HOW? How do you "get user information in /auth request too by session id"?
Please ask for anything else you need to straighten me out.
I'm stumped. I have tried some dumb stuff already!
The variable is undefined in other routes if you don't log in first in the browser. Here is my test code:
var express = require('express');
var cors = require('cors');
app = express();
app.use(cors());
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'this is a test' }));
app.use(express.static(require('path').join(__dirname, 'public')));
app.get('/login', function(req, res) {
req.session.uid = 'user001';
res.send(req.session);
});
app.get('*', function(req, res) {
res.send(req.session);
});
app.listen(8080);
First visit http://localhost/login in the browser. Then visit other URLs(e.g., http://localhost/test) in this browser, the user id in the session is returned. So maybe there is something wrong in other parts of your code.
Test settings:
Ubuntu Desktop 13.10, 64 bit
Node 0.10.26
NPM 1.4.4
Express 3.4.8
cors 2.2.0

Categories

Resources