Avoiding image logging in Express.js - node.js

I'm using Express.JS in node, and i saw that in the log file generate by the logger. I would like to avoid the logging of the image, how could I set the type of requests I want to save in the log file?
Thanks!

This should do the trick
var express = require("express");
var logger = express.logger();
var app = express.createServer();
var conditionalLogger = function (req, res, next) {
if (!(/\.(png|jpg|gif|jpeg)$/i).test(req.path)) {
logger(req, res, next);
} else {
next();
}
}
app.use(conditionalLogger);
app.use(express.static("./public"));
app.listen(3456);

Related

How to save POST to global variable in node

I am sending json by POST to nodejs, I declared router.post in index.js, (/routes)
How I can save it so I can actually use that later on? Keep in mind that every 60sec I am getting new data that should replace the old one.
I am listening on port 3000
var express = require('express');
var router = express.Router();
var saveme
/* GET home page. */
router.get('/index', function(req, res, next) {
res.render('index', { title: 'RLH' });
});
router.post('/index', function(req, res, next) {
data = req.body;
console.log('OK')
});
module.exports = router;
I don't know how can I save what I get trough POST, so later on I can use it on my website.
There are multiple ways to use Global variable:
Method1
Using app.locals :
declare app.locals.data = {}; in main file (ex:server.js)
var app = express();
app.locals.data = {};
app.locals available to req object as req.app.locals. When you have new data you can update it as :
req.app.locals.data = req.body;
Method2
Using global object
Assign new data as global.data = req.body
You can always access data as global.data in same or different module
Method3(Recommended)
Create file globaldata.js with below code
module.exports = {};
Import globaldata.js where you need to access or update global data as
var globaldata = require('./globaldata.js');
globaldata = req.body;
What is recommended? global method for small apps, module.exports for big apps.
You can read below ref. for more details:
https://www.hacksparrow.com/nodejs/global-variables-in-node-js.html
http://expressjs.com/en/api.html#app.locals
If by saving the data you mean storing it in a variable you can do:
var express = require('express');
var router = express.Router();
var saveme;
/* GET home page. */
router.get('/index', function(req, res, next) {
if (saveme) {
// you can use `saveme`
res.render('index' + saveme.toString(), { title: 'RLH' });
}
else {
res.render('index', { title: 'RLH' });
}
});
router.post('/index', function(req, res, next) {
data = req.body;
// set `saveme`
saveme = data;
});
module.exports = router;

Sharing variable across multiple files

Would like to know a "good" way of sharing a variable for the following scenario.
My server.js file includes an authenticator.js file like so:
var authenticator = require('./server/services/authenticator')(app);
app.use(authenticator);
Within the authenticator.js file there is a variable called privateKey:
module.exports = function (app) {
var authenticator = function (req, res, next) {
//do some stuff here
var privateKey = 'value from Basic Auth header'
};
return authenticator;
};
My api.js file now needs this privateKey variable.
I include the api.js file from my server.js in the same way:
var api = require('./server/api')(app);
app.use('/v1', api);
and I would like to pass the privateKey too using something like:
var api = require('./server/api')(app, privateKey);
QUESTION: How can I make privateKey available in my server.js file so that I can pass it to the api.js file?
You could attach it to the req variable
module.exports = function(app) {
var authenticator = function(req, res, next) {
//do some stuff here
req.privateKey = 'value from Basic Auth header'; //This can be shared accross middlewares.
next(); //don't forget to call this.
};
return authenticator;
};
server.js
var api = require('./server/api')(app);
app.use('/v1', api);
api.js
module.exports = function(api) {
var api = function(req, res, next) {
var privateKey = req.privateKey; //this is how we can use it
//do something with it
next();
};
return api;
};
}

Trying to upload a file to a nodejs web service

I'm trying to create a simple web service in nodejs that accepts a file and saves it.
Here is my code.
var express = require('express');
var app = express();
var fs = require('fs');
var sys = require('sys');
app.listen(8080);
app.post('/upload', function(req, res) {
console.log(req.files);
var fileKey = Object.keys(req.files)[0];
var file = req.files[fileKey];
fs.readFile(file.path, function(err, data) {
fs.writeFile(__dirname, data, function(err) {
res.redirect("back");
});
});
});
I'm using fiddler to upload the file.
console.log(req.files);
gives undefined. An exception is also thrown:
Object.keys called on non-object
Any idea what I may be doing wrong?
You don't seem to be using the bodyParser middleware which is required to parse uploads (amongst other things):
app.use(express.bodyParser());
app.post('/upload', function(req, res) { ... });

Pass configuration to controller

I am building a node.js app that will upload files to my S3 bucket using knox. I am able to interact with S3 as expected, but I would like to make my controller to receive configuration so I can dynamically construct my client with configuration values.
My questions is how do I get configuration paramters down the call stack to my controller without being careless?
Disclaimer: I am rather new to Node.js so it could be simply my lack of knowledge in the difference between exports. and module.exports.*
Here is an example of how the interaction works with my code:
app.js
...
config = require('./config/config')['env'];
require('./config/router')(app, config);
...
router.js
module.exports = function(app, config) {
...
var controller = require('../app/controllers/home'); //Is there a way for me to pass config here?
app.post('/upload', controller.upload); //Or here?
...
}
home.js
var knox = require('knox');
var client = knox.createClient({ ... }); //I want to use config.key, config.secret, etc instead of hard-coded values
...
exports.upload = function(req, res) {
//Use client
}
...
Try doing something like this...
var config = require('./config/config')['env'];
// The use function will be called before your
// action, because it is registered first.
app.use(function (req, res, next) {
// Assign the config to the req object
req.config = config;
// Call the next function in the pipeline (your controller actions).
return next();
});
// After app.use you register your controller action
app.post('/upload', controller.upload);
And then in your controller action...
exports.upload = function(req, res) {
//Your config should be here...
console.log(req.config);
}
Ps. I can not try it right now, but I solved a similar issue like this.
You can pass the configuration in as a parameter to you controller
Controller
// controller.js file
module.exports = function(req, res, config) {
console.log('config parameter passed to controller', config);
res.end('config passed')
}
App
// index.js file with the express app
var controller = require('./controller');
var config = {
key1: 'foo'
};
var express = require('express');
var app = express();
var port = 3000;
app.get('/', function(req, res){
controller(req, res, config);
});
app.listen(port);
console.log('app listening on port', 3000);
Demo
You can check out the github repo for a complete example
Alternative approach if you want to call multiple functions from one single route, this will do it.
Route
var users = require('../controllers/users');
app.route('/login').post(function(req, res){
if(users.authenticate()){
console.log('valid user');
if(users.createUser())
{
console.log('user created');
}
}
});
Controller
exports.authenticate = function(req, res, next) {
return true;
};
exports.createUser = function(req, res, next) {
return true;
};

How to include route handlers in multiple files in Express? [duplicate]

This question already has answers here:
How to separate routes on Node.js and Express 4?
(9 answers)
Closed 1 year ago.
In my NodeJS express application I have app.js that has a few common routes. Then in a wf.js file I would like to define a few more routes.
How can I get app.js to recognize other route handlers defined in wf.js file?
A simple require does not seem to work.
If you want to put the routes in a separate file, for example routes.js, you can create the routes.js file in this way:
module.exports = function(app){
app.get('/login', function(req, res){
res.render('login', {
title: 'Express Login'
});
});
//other routes..
}
And then you can require it from app.js passing the app object in this way:
require('./routes')(app);
Have a look at these examples: https://github.com/visionmedia/express/tree/master/examples/route-separation
In Express 4.x you can get an instance of the router object and import another file that contains more routes. You can even do this recursively so your routes import other routes allowing you to create easy-to-maintain URL paths.
For example, if I have a separate route file for my /tests endpoint already and want to add a new set of routes for /tests/automated I may want to break these /automated routes out into a another file to keep my /test file small and easy to manage. It also lets you logically group routes together by URL path which can be really convenient.
Contents of ./app.js:
var express = require('express'),
app = express();
var testRoutes = require('./routes/tests');
// Import my test routes into the path '/test'
app.use('/tests', testRoutes);
Contents of ./routes/tests.js:
var express = require('express'),
router = express.Router();
var automatedRoutes = require('./testRoutes/automated');
router
// Add a binding to handle '/tests'
.get('/', function(){
// render the /tests view
})
// Import my automated routes into the path '/tests/automated'
// This works because we're already within the '/tests' route
// so we're simply appending more routes to the '/tests' endpoint
.use('/automated', automatedRoutes);
module.exports = router;
Contents of ./routes/testRoutes/automated.js:
var express = require('express'),
router = express.Router();
router
// Add a binding for '/tests/automated/'
.get('/', function(){
// render the /tests/automated view
})
module.exports = router;
Building on #ShadowCloud 's example I was able to dynamically include all routes in a sub directory.
routes/index.js
var fs = require('fs');
module.exports = function(app){
fs.readdirSync(__dirname).forEach(function(file) {
if (file == "index.js") return;
var name = file.substr(0, file.indexOf('.'));
require('./' + name)(app);
});
}
Then placing route files in the routes directory like so:
routes/test1.js
module.exports = function(app){
app.get('/test1/', function(req, res){
//...
});
//other routes..
}
Repeating that for as many times as I needed and then finally in app.js placing
require('./routes')(app);
If you're using express-4.x with TypeScript and ES6, this would be the best template to use:
src/api/login.ts
import express, { Router, Request, Response } from "express";
const router: Router = express.Router();
// POST /user/signin
router.post('/signin', async (req: Request, res: Response) => {
try {
res.send('OK');
} catch (e) {
res.status(500).send(e.toString());
}
});
export default router;
src/app.ts
import express, { Request, Response } from "express";
import compression from "compression"; // compresses requests
import expressValidator from "express-validator";
import bodyParser from "body-parser";
import login from './api/login';
const app = express();
app.use(compression());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(expressValidator());
app.get('/public/hc', (req: Request, res: Response) => {
res.send('OK');
});
app.use('/user', login);
app.listen(8080, () => {
console.log("Press CTRL-C to stop\n");
});
Much cleaner than using var and module.exports.
Full recursive routing of all .js files inside /routes folder, put this in app.js.
// Initialize ALL routes including subfolders
var fs = require('fs');
var path = require('path');
function recursiveRoutes(folderName) {
fs.readdirSync(folderName).forEach(function(file) {
var fullName = path.join(folderName, file);
var stat = fs.lstatSync(fullName);
if (stat.isDirectory()) {
recursiveRoutes(fullName);
} else if (file.toLowerCase().indexOf('.js')) {
require('./' + fullName)(app);
console.log("require('" + fullName + "')");
}
});
}
recursiveRoutes('routes'); // Initialize it
in /routes you put whatevername.js and initialize your routes like this:
module.exports = function(app) {
app.get('/', function(req, res) {
res.render('index', { title: 'index' });
});
app.get('/contactus', function(req, res) {
res.render('contactus', { title: 'contactus' });
});
}
And build yet more on the previous answer, this version of routes/index.js will ignore any files not ending in .js (and itself)
var fs = require('fs');
module.exports = function(app) {
fs.readdirSync(__dirname).forEach(function(file) {
if (file === "index.js" || file.substr(file.lastIndexOf('.') + 1) !== 'js')
return;
var name = file.substr(0, file.indexOf('.'));
require('./' + name)(app);
});
}
I am trying to update this answer with "express": "^4.16.3". This answer is similar to the one from ShortRound1911.
server.js:
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const db = require('./src/config/db');
const routes = require('./src/routes');
const port = 3001;
const app = new express();
//...use body-parser
app.use(bodyParser.urlencoded({ extended: true }));
//...fire connection
mongoose.connect(db.url, (err, database) => {
if (err) return console.log(err);
//...fire the routes
app.use('/', routes);
app.listen(port, () => {
console.log('we are live on ' + port);
});
});
/src/routes/index.js:
const express = require('express');
const app = express();
const siswaRoute = require('./siswa_route');
app.get('/', (req, res) => {
res.json({item: 'Welcome ini separated page...'});
})
.use('/siswa', siswaRoute);
module.exports = app;
/src/routes/siswa_route.js:
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.json({item: 'Siswa page...'});
});
module.exports = app;
If you want a separate .js file to better organize your routes, just create a variable in the app.js file pointing to its location in the filesystem:
var wf = require(./routes/wf);
then,
app.get('/wf', wf.foo );
where .foo is some function declared in your wf.js file. e.g
// wf.js file
exports.foo = function(req,res){
console.log(` request object is ${req}, response object is ${res} `);
}
One tweak to all of these answers:
var routes = fs.readdirSync('routes')
.filter(function(v){
return (/.js$/).test(v);
});
Just use a regex to filter via testing each file in the array. It is not recursive, but it will filter out folders that don't end in .js
I know this is an old question, but I was trying to figure out something like for myself and this is the place I ended up on, so I wanted to put my solution to a similar problem in case someone else has the same issues I'm having. There's a nice node module out there called consign that does a lot of the file system stuff that is seen here for you (ie - no readdirSync stuff). For example:
I have a restful API application I'm trying to build and I want to put all of the requests that go to '/api/*' to be authenticated and I want to store all of my routes that go in api into their own directory (let's just call it 'api'). In the main part of the app:
app.use('/api', [authenticationMiddlewareFunction], require('./routes/api'));
Inside of the routes directory, I have a directory called "api" and a file called api.js. In api.js, I simply have:
var express = require('express');
var router = express.Router();
var consign = require('consign');
// get all routes inside the api directory and attach them to the api router
// all of these routes should be behind authorization
consign({cwd: 'routes'})
.include('api')
.into(router);
module.exports = router;
Everything worked as expected. Hope this helps someone.
index.js
const express = require("express");
const app = express();
const http = require('http');
const server = http.createServer(app).listen(3000);
const router = (global.router = (express.Router()));
app.use('/books', require('./routes/books'))
app.use('/users', require('./routes/users'))
app.use(router);
routes/users.js
const router = global.router
router.get('/', (req, res) => {
res.jsonp({name: 'John Smith'})
}
module.exports = router
routes/books.js
const router = global.router
router.get('/', (req, res) => {
res.jsonp({name: 'Dreams from My Father by Barack Obama'})
}
module.exports = router
if you have your server running local (http://localhost:3000) then
// Users
curl --request GET 'localhost:3000/users' => {name: 'John Smith'}
// Books
curl --request GET 'localhost:3000/books' => {name: 'Dreams from My Father by Barack Obama'}
I wrote a small plugin for doing this! got sick of writing the same code over and over.
https://www.npmjs.com/package/js-file-req
Hope it helps.
you can put all route functions in other files(modules) , and link it to the main server file.
in the main express file, add a function that will link the module to the server:
function link_routes(app, route_collection){
route_collection['get'].forEach(route => app.get(route.path, route.func));
route_collection['post'].forEach(route => app.post(route.path, route.func));
route_collection['delete'].forEach(route => app.delete(route.path, route.func));
route_collection['put'].forEach(route => app.put(route.path, route.func));
}
and call that function for each route model:
link_routes(app, require('./login.js'))
in the module files(for example - login.js file), define the functions as usual:
const login_screen = (req, res) => {
res.sendFile(`${__dirname}/pages/login.html`);
};
const forgot_password = (req, res) => {
console.log('we will reset the password here')
}
and export it with the request method as a key and the value is an array of objects, each with path and function keys.
module.exports = {
get: [{path:'/',func:login_screen}, {...} ],
post: [{path:'/login:forgotPassword', func:forgot_password}]
};

Resources