Express JS 4 sends console.log output - node.js

This is very strange in that Express JS is sending the console.log output to the client without res.send being used.
Calling the /api POST endpoint shows the "Hello" from the parseJSON back to the client.
How can I get this to stop?
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json({
limit: '50mb'
}));
app.use(bodyParser.urlencoded({
extended: false
}));
app.get('*', function(req, res, next) {
var err = new Error();
err.status = 404;
next(err);
});
// handling 404 errors
app.use(function(err, req, res, next) {
if (err.status !== 404) {
return next();
}
res.send(err.message || '** 404 error **');
});
app.post('/api', function(req, res) {
parseJSON(req.body);
res.status(200).end();
});
app.listen(80);
function parseJSON(jsonData)
{
console.log("HELLO");
}

Related

How to prevent response from server directly display in browser?

I am using express.js framework for my node.js server.
This is how I setup my server.
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 index = require('./routes/index');
var createUsers = require('./routes/users/createUsers');
var updateUsers = require('./routes/users/updateUsers');
var deleteUsers = require('./routes/users/deleteUsers');
var readUsers = require('./routes/users/readUsers');
var app = express();
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
var mysql = require("mysql");
//Database connection
app.use(function(req, res, next){
res.locals.connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'password',
database : 'project'
});
res.locals.connection.connect();
next();
});
// 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(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/createUsers', createUsers);
app.use('/updateUsers', updateUsers);
app.use('/deleteUsers', deleteUsers);
app.use('/readUsers', readUsers);
// 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 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.ejs');
});
var http = require('http');
module.exports = app;
var server = http.createServer(app);
server.listen(4000);
This is my readUsers.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
//console.log("pending data");
res.locals.connection.query('SELECT id,name,email,username,address,phone,status FROM user', function (error, results, fields) {
if (error) throw error;
res.send(JSON.stringify(results));
});
});
module.exports = router;
My server is listen at port 4000. My react frontend componentDidMount() function use axios.get("http://localhost:4000/readUsers") to read the data from database and it worked well.
However, if I directly type in http://localhost:4000/readUsers in my browser, it will directly connect to my database and read all User data and displayed the data in browser. This is not I want because everyone can read my data if they know this address. Any way to prevent this issue?
Add middleware to your router. here's the doc Router-level middleware
Express have many middleware, one of it is route-level middleware. This middleware handle anything between users and your function.
Here is the example i fetch from the documentation.
var app = express()
var router = express.Router()
// a middleware function with no mount path. This code is executed for every request to the router
router.use(function (req, res, next) {
console.log('Time:', Date.now())
next()
})
// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
router.use('/user/:id', function (req, res, next) {
console.log('Request URL:', req.originalUrl)
next()
}, function (req, res, next) {
console.log('Request Type:', req.method)
next()
})
In your case you may add some permission validation before request. Usually it's an API key, but it can be anything, secret word in header, secret parameter, everything.
Here is the example for your case.
function isPermitted(req, res, next) {
var permitted = false;
// Your validation here, is your user permitted with this access or not.
if (permitted) {
next();
} else {
res.send('Sorry, you are not belong here.');
}
}
/* GET home page. */
router.get('/', isPermitted, function(req, res, next) {
//console.log("pending data");
res.locals.connection.query('SELECT id,name,email,username,address,phone,status FROM user', function (error, results, fields) {
if (error) throw error;
res.send(JSON.stringify(results));
});
});
Use POST instead of GET as method for request.

How do you test a expressApp.post()?

I a C# developer trying to learn node.js / Dialogflow on the fly. I am trying to create a webhook in node.js on Azure that I would use as a fulfillment for my Dialogflow project.
My understanding is that I need to convert the following
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
to
expressApp.post( '/dialogflowFulfillment', (request, response) => {
}
'use strict';
var debug = require('debug');
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', 'pug');
// 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: false }));
app.use(cookieParser());
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
// 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: {}
});
});
app.post('/dialogflowFulfillment', function (req, res) {
res.send('POST request to homepage');
});
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function () {
debug('Express server listening on port ' + server.address().port);
});
My question is how do I test the 'expressApp.post()' so I know its getting called. I used Visual Studio 2017 and created a blank node.js express app then I added the post function. I run app and then use the Postman app to send a post request to the url (localhost:3000)/dialogflowFulfillment but I get a 404 error.
What am I missing? Thank you for your help!
You have to move your function above the error handling:
app.use('/', routes);
app.use('/users', users);
// Put your function right here
app.post('/dialogflowFulfillment', function (req, res) {
res.send('POST request to homepage');
});
// Catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
The function to catch 404 and forward to error handling does the following as described here:
Calls to next() and next(err) indicate that the current handler is
complete and in what state. next(err) will skip all remaining
handlers in the chain except for those that are set up to handle
errors as described above.
Express sends 404 HTTP error because the sequence of adding middlewares does matter.
As far as you added 404 error sending middleware right after app.use('/users', users); middleware, 404 middleware will be executed next - it will throw send an error ( next(err); ) to next middleware which catches all errors and sends response. To resolve this issue you need to .use error handling middlewares right after all other middlewares:
app.post('/dialogflowFulfillment', function (req, res) {
res.send('POST request to homepage');
});
// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(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: {}
});
});

Always returning 500 error

var express = require('express');
var router = express.Router();
router.post("/", function(req, res, next) {
console.log('Yes1');
if(!req.body.username || !req.body.password){
console.log('Yes2');
return res.status(401).json(JSON.stringify({
error: 'Username or Password are not set'
}));
}else{
console.log('Yes3');
return res.status(200).json(JSON.stringify({
data: 'Okay'
}));
}
//error handler
router.use(function(err, req, res, next) {
res.status(500).json(JSON.stringify({
error: err
}));
});
module.exports = router;
From the front end I am sending a username and password. I am expecting to either be receiving errors 200 or 401. For some reason though I receiving error 500 which is the default error handler. I am not sure how it is coming here. On my server console Yes1 and Yes2 are being printed so why am I not getting error 401?
I don't know if you have more code or not, but you need to install your router with app.use('/', router).
You also need to install the body-parser middleware to be able to parse req.body.
Your whole application should look something like this:
// router.js
var express = require('express');
var router = express.Router();
router.post("/", function(req, res, next) {
console.log('Yes1');
console.log(req.body);
if(!req.body.username || !req.body.password){
console.log('Yes2');
return res.status(401).json(JSON.stringify({
error: 'Username or Password are not set'
}));
}else{
console.log('Yes3');
return res.status(200).json(JSON.stringify({
data: 'Okay'
}));
}
});
//error handler
router.use(function(err, req, res, next) {
res.status(500).json(JSON.stringify({
error: err
}));
});
module.exports = router;
// server.js
var express = require('express');
var bodyParser = require('body-parser');
var customRouter = require('./router.js');
var app = express();
app.use(bodyParser.json()); // for parsing application/json
app.use('/', customRouter);
app.listen(3000, function () {
console.log('Listening on port 3000...');
});
See error handling and routing documentation.
It appears that your middleware handler is firing, because 401 is an error, and you are resetting the status to 500.

post using restler and node.js is not returning

I am trying to post using restler and return the response to client but response never returns .Below is code I am using and response is just hanging
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var rest = require('restler');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = 3001; // can also get it from process.env.PORT
var router = express.Router();
//this is like interceptor for every route to validate all requests, logging for analytics
router.use(function (req, res, next) {
console.log('route intercepted');
next(); // make sure we go to the next routes and don't stop here
});
router.get('/', function(req, res) {
res.json({ message: "welcome to restful node proxy layer to business processes" });
});
router.route('/someroute').post(function(req, res) {
rest.postJson('http://localhost/api/sg', req.body).on('complete', function(data, response) {
console.log(response);
}
).on('error', function(data, response) {
console.log('error');
});
});
app.use('/api', router); //all routes are prefixed with /api
app.listen(port);
console.log("server is running magic happens from here");

node/express - exporting controller functionality

I am building a Node API on express which takes GET requests and uses the parameters supplied by the client to return the results of GET requests made to other API's.
In order to keep the controller thin when adding more API's I would like to export the logic within the controller into a separate .js file, and module.export those functions back in, to be used in the controller. The problem here is that the functions that are being exported do not appear to be visible within the controller.
Pasted below is before and after code to illustrate progress made so far.
app.js (before) - see router.get('/')
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 request = require('request');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
var router = express.Router();
if ( app.get('env') === 'development') {
var dotenv = require('dotenv');
dotenv.load();
};
var prodAdv = require('./lib/prod-adv.js')
// 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(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/api', router);
// 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: {}
});
});
router.get('/', function(req, res) {
request('https://openapi.etsy.com/v2/listings/active?includes=Images&keywords=' + req.param('SearchIndex') + '&limit=100&api_key=' + process.env.ETSY_KEY, function(error, response, body) {
res.header({'Access-Control-Allow-Origin': '*'});
var data = JSON.parse(body);
res.json(data);
});
});
router.use('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, accept, authorization");
next();
});
var server = app.listen(9876, function() {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s',host,port);
});
module.exports = app;
This approach works, returning JSON objects. However the following approach to try and export the code does not work.
apiCaller.js
var express = require('express');
var app = express();
if ( app.get('env') === 'development' ) { var dotenv = require('dotenv'); dotenv.load(); };
var request = require('request');
var call, response;
var call = function(searchIndex) {
return request('https://openapi.etsy.com/v2/listings/active?includes=Images&keywords=' + searchIndex + '&limit=100&api_key=' + process.env.ETSY_KEY, function(error, response, body) {
response = JSON.parse(body);
});
};
module.exports.response = response;
module.exports.call = call;
app.js (after)
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 squid = require('./lib/apiCaller.js');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
var router = express.Router();
if ( app.get('env') === 'development') {
var dotenv = require('dotenv');
dotenv.load();
};
var prodAdv = require('./lib/prod-adv.js')
// 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(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/api', router);
// 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: {}
});
});
router.get('/', function(req, res) {
squid.call(req.param('SearchIndex'));
res.header({'Access-Control-Allow-Origin': '*'});
res.json(squid.response);
});
router.use('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, accept, authorization");
next();
});
var server = app.listen(9876, function() {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s',host,port);
});
module.exports = app;
What occurs now in the browser is a 200 OK with an empty response body. console.logging the responses return undefined objects.
You need to rewrite your call function to have a callback since request(...) is asyncronous
var call = function(searchIndex, callback) {
request('https://openapi.etsy.com/v2/listings/active?includes=Images&keywords=' + searchIndex + '&limit=100&api_key=' + process.env.ETSY_KEY, function(error, response, body) {
if (!error && response.statusCode == 200) {
return callback(null, JSON.parse(body));
}
callback('error');
});
};
Only export call function, there's no need to export or even use response and no need for this line
var call, response;
Now you also need to use it a bit different way
router.get('/', function(req, res) {
res.header({'Access-Control-Allow-Origin': '*'});
squid.call(req.param('SearchIndex'), function(err, data){
if(!err) return res.json(data);
res.json({error: err});
});
});

Resources