Code doesn't serve my static html files in the publlic folder - javascript

Exploring express framework. Learning the express.static middleware but it doesn't function the way I expect it to.
Code:
const express = require("express");
const app = express();
app.use((req, res, next) =>{
express.static('public');
next();
});
app.use((req, res) => {
console.log("Starting first middleware");
});
app.listen(3000);
The above code doesn't serve my static html files in the publlic folder. The public folder is on the same directory as this JS file, and when I for instance use the URL http://localhost:3000/home.html to try to access the home.html file in the public folder I cannot access it.
When I switch up the order that the express.static is last it does serve my static html file in the public folder.
Code:
app.use((req, res, next) => {
console.log("Starting first middleware");
next();
});
app.use(express.static('public'));
Question:
Why doesn't my app in the first code example serve the static files?

express.static is a function that returns another function (middleware), and Express middlewares expect 2 or 3 parameters (req, res[, next]).
When it is used as a callback, like this:
app.use(express.static('public'));
you don't need to explicitly provide parameters to it, since app.use will provide them for you.
However, when you use it yourself, you need to explicitly call the function with its parameters:
app.use((req, res, next) =>{
express.static('public')(req, res, next);
next();
});
In your first example, you were generating the middleware, but not executing it.

There is a fundemental difference between the two snippets. You see the first one you are basically calling the function express.static with argument 'public' inside the callback function of a middleware you declared, this only will return a function that will not be used in next middlewares as no arguments passed to it; the req object should be passed to it. However in the second one this will return a function that can use the req object which is passed along with the res normally in the app.use. Take a look at some of the source code of the 'static' function to get an idea :
function serveStatic (root, options) {
if (!root) {
throw new TypeError('root path required')
}
if (typeof root !== 'string') {
throw new TypeError('root path must be a string')
}
// copy options object
var opts = Object.create(options || null)
// fall-though
var fallthrough = opts.fallthrough !== false
// default redirect
var redirect = opts.redirect !== false
// headers listener
var setHeaders = opts.setHeaders
if (setHeaders && typeof setHeaders !== 'function') {
throw new TypeError('option setHeaders must be function')
}
// setup options for send
opts.maxage = opts.maxage || opts.maxAge || 0
opts.root = resolve(root)
// construct directory listener
var onDirectory = redirect
? createRedirectDirectoryListener()
: createNotFoundDirectoryListener()
return function serveStatic (req, res, next) { // the funciton returned
if (req.method !== 'GET' && req.method !== 'HEAD') {
if (fallthrough) {
return next()
}
// method not allowed
res.statusCode = 405
res.setHeader('Allow', 'GET, HEAD')
res.setHeader('Content-Length', '0')
res.end()
return
}
var forwardError = !fallthrough
var originalUrl = parseUrl.original(req)
var path = parseUrl(req).pathname
// make sure redirect occurs at mount
if (path === '/' && originalUrl.pathname.substr(-1) !== '/') {
path = ''
}
// create send stream
var stream = send(req, path, opts)
//rest of code...

Related

Calling Express Route internally from inside NodeJS

I have an ExpressJS routing for my API and I want to call it from within NodeJS
var api = require('./routes/api')
app.use('/api', api);
and inside my ./routes/api.js file
var express = require('express');
var router = express.Router();
router.use('/update', require('./update'));
module.exports = router;
so if I want to call /api/update/something/:withParam from my front end its all find, but I need to call this from within another aspect of my NodeJS script without having to redefine the whole function again in 2nd location
I have tried using the HTTP module from inside but I just get a "ECONNREFUSED" error
http.get('/api/update/something/:withParam', function(res) {
console.log("Got response: " + res.statusCode);
res.resume();
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
I understand the idea behind Express is to create routes, but how do I internally call them
The 'usual' or 'correct' way to handle this would be to have the function you want to call broken out by itself, detached from any route definitions. Perhaps in its own module, but not necessarily. Then just call it wherever you need it. Like so:
function updateSomething(thing) {
return myDb.save(thing);
}
// elsewhere:
router.put('/api/update/something/:withParam', function(req, res) {
updateSomething(req.params.withParam)
.then(function() { res.send(200, 'ok'); });
});
// another place:
function someOtherFunction() {
// other code...
updateSomething(...);
// ..
}
This is an easy way to do an internal redirect in Express 4:
The function that magic can do is: app._router.handle()
Testing: We make a request to home "/" and redirect it to otherPath "/other/path"
var app = express()
function otherPath(req, res, next) {
return res.send('ok')
}
function home(req, res, next) {
req.url = '/other/path'
/* Uncomment the next line if you want to change the method */
// req.method = 'POST'
return app._router.handle(req, res, next)
}
app.get('/other/path', otherPath)
app.get('/', home)
I've made a dedicated middleware for this : uest.
Available within req it allows you to req.uest another route (from a given route).
It forwards original cookies to subsequent requests, and keeps req.session in sync across requests, for ex:
app.post('/login', async (req, res, next) => {
const {username, password} = req.body
const {body: session} = await req.uest({
method: 'POST',
url: '/api/sessions',
body: {username, password}
}).catch(next)
console.log(`Welcome back ${session.user.firstname}!`
res.redirect('/profile')
})
It supports Promise, await and error-first callback.
See the README for more details
Separate your app and server files with the app being imported into the server file.
In the place you want to call your app internally, you can import you app as well as 'request' from 'supertest'. Then you can write
request(app).post('/someroute').send({
id: 'ecf8d501-5abe-46a9-984e-e081ac925def',
etc....
});`
This is another way.
const app = require('express')()
const axios = require('axios')
const log = console.log
const PORT = 3000
const URL = 'http://localhost:' + PORT
const apiPath = (path) => URL + path
app.get('/a', (req, res) => {
res.json('yoy')
})
app.get('/b', async (req, res) => {
let a = await axios.get(apiPath('/a'))
res.json(a.data)
})
app.listen(PORT)

Node app.js use function how its recommended

Im having node app which using express i've server.js app.js etc
I need to use as middelware the following code
var upload = multer({
storage: storage
});
app.use(upload.single('file'));
app.use('/', rot, function (req, res, next) {
next();
});
But before the var upload = multer... I want to run the following
code
var mkdirSync = function (path) {
try {
fs.mkdirSync(path);
} catch(e) {
if ( e.code != 'EEXIST' ) throw e;
}
}
mkdirSync( 'uploads/');
How should I do it nicely? add the code of mkdir before the upload multer
You can create another middleware for this purpose, since app.use accepts multiple middleware functions.
app.use(function(req, res, next) {
fs.mkdir(path, function(e){
if(!!e && e.code !== 'EEXIST'){
next(e);
return;
}
next();
});
}, upload.single('file'));
The above code should work. When you pass an error into the next middleware, express will know to skip all the following middleware functions and go straight to the error handler.
EDIT: I would recommend using the non-sync version of mkdir, and avoiding the try/catch block altogether.
EDIT 2: Maybe I am mistaken, and all you are looking to do is make sure the storage directory exists? If this is the case then simply doing the following will work:
mkdirSync(storage);
var upload = multer({
storage: storage
});
app.use(upload.single('file'));
app.use('/', rot, function (req, res, next) {
next();
});
Its better to do like this.
//dir.js
exports.makeDir = function(path) {
console.log(path);
try {
fs.mkdirSync(path);
} catch (e) {
if (e.code != 'EEXIST') throw e;
}
}
And in your app.js
var varMkDir = require('./dir');
app.use(varMkDir.makeDir('uploads/'));
EDIT :
app.use(function(){
varMkDir.makeDir('uploads/');
})

Exclude route from express middleware

I have a node app sitting like a firewall/dispatcher in front of other micro services and it uses a middleware chain like below:
...
app.use app_lookup
app.use timestamp_validator
app.use request_body
app.use checksum_validator
app.use rateLimiter
app.use whitelist
app.use proxy
...
However for a particular GET route I want to skip all of them except rateLimiter and proxy. Is their a way to set a filter like a Rails before_filter using :except/:only?
Even though there is no build-in middleware filter system in expressjs, you can achieve this in at least two ways.
First method is to mount all middlewares that you want to skip to a regular expression path than includes a negative lookup:
// Skip all middleware except rateLimiter and proxy when route is /example_route
app.use(/\/((?!example_route).)*/, app_lookup);
app.use(/\/((?!example_route).)*/, timestamp_validator);
app.use(/\/((?!example_route).)*/, request_body);
app.use(/\/((?!example_route).)*/, checksum_validator);
app.use(rateLimiter);
app.use(/\/((?!example_route).)*/, whitelist);
app.use(proxy);
Second method, probably more readable and cleaner one, is to wrap your middleware with a small helper function:
var unless = function(path, middleware) {
return function(req, res, next) {
if (path === req.path) {
return next();
} else {
return middleware(req, res, next);
}
};
};
app.use(unless('/example_route', app_lookup));
app.use(unless('/example_route', timestamp_validator));
app.use(unless('/example_route', request_body));
app.use(unless('/example_route', checksum_validator));
app.use(rateLimiter);
app.use(unless('/example_route', whitelist));
app.use(proxy);
If you need more powerfull route matching than simple path === req.path you can use path-to-regexp module that is used internally by Express.
UPDATE :- In express 4.17 req.path returns only '/', so use req.baseUrl :
var unless = function(path, middleware) {
return function(req, res, next) {
if (path === req.baseUrl) {
return next();
} else {
return middleware(req, res, next);
}
};
};
Built upon the answer from #lukaszfiszer as I wanted more than one route excluded.
You can add as many as you want here.
var unless = function(middleware, ...paths) {
return function(req, res, next) {
const pathCheck = paths.some(path => path === req.path);
pathCheck ? next() : middleware(req, res, next);
};
};
app.use(unless(redirectPage, "/user/login", "/user/register"));
Can't add as comment sorry.
You can also skip route like this by putting a condition on req.originalUrl:
app.use(function (req, res, next) {
if (req.originalUrl === '/api/login') {
return next();
} else {
//DO SOMETHING
}
I use this regular expression with success : /^\/(?!path1|pathn).*$/.
There's a lot of good answers here. I needed a slightly different answer though.
I wanted to be able to exclude middleware from all HTTP PUT requests. So I created a more general version of the unless function that allows a predicate to be passed in:
function unless(pred, middleware) {
return (req, res, next) => {
if (pred(req)) {
next(); // Skip this middleware.
}
else {
middleware(req, res, next); // Allow this middleware.
}
}
}
Example usage:
app.use(unless(req => req.method === "PUT", bodyParser.json()));
You can define some routes like below.
app.use(/\/((?!route1|route2).)*/, (req, res, next) => {
//A personal middleware
//code
next();//Will call the app.get(), app.post() or other
});
Here's an example of using path-to-regexp as #lukaszfiszer's answer suggests:
import { RequestHandler } from 'express';
import pathToRegexp from 'path-to-regexp';
const unless = (
paths: pathToRegexp.Path,
middleware: RequestHandler
): RequestHandler => {
const regex = pathToRegexp(paths);
return (req, res, next) =>
regex.exec(req.url) ? next() : middleware(req, res, next);
};
export default unless;
The way I achieved this is by setting up a middleware for a specific path like so
app.use("/routeNeedingAllMiddleware", middleware1);
app.use("/routeNeedingAllMiddleware", middleware2);
app.use("/routeNeedingAllMiddleware", middleware3);
app.use("/routeNeedingAllMiddleware", middleware4);
and then setting up my routes like so
app.post("/routeNeedingAllMiddleware/route1", route1Handler);
app.post("/routeNeedingAllMiddleware/route2", route2Handler);
For the other special route that doesn't need all the middleware, we setup another route like so
app.use("/routeNeedingSomeMiddleware", middleware2);
app.use("/routeNeedingSomeMiddleware", middleware4);
and then setting up the corresponding route like so
app.post("/routeNeedingSomeMiddleware/specialRoute", specialRouteHandler);
The Express documentation for this is available here
In my case I used part of answers posted yet to override original app.use
const unless = ( route, middleware ) => {
return ( req, res, next ) => {
if ( req.originalUrl.startsWith( route + '/' ) ) {
return next();
} else {
return middleware( req, res, next );
}
};
};
const filteredRoute = '/myapi'; // Route to filter and subroute
const origUse = app.use;
app.use = function ( ...callbacks ) {
if ( !callbacks.length ) throw new Error( '.use() method requires at least one function' );
if ( typeof callbacks[0] ==='string' ) {
if ( !( callbacks.length -1 ) ) throw new Error( '.use() method requires at least one function' );
const route = callbacks.shift();
for ( let i = 0; i < callbacks.length; i++ ) {
origUse.call( this, route, unless( filteredRoute, callbacks[i] ) );
}
} else {
for ( let i = 0; i < callbacks.length; i++ ) {
origUse.call( this, unless( filteredRoute, callbacks[i] ) );
}
}
};
Improved upon #Geelie's answer with added types:
import {Request, Response, NextFunction, Handler} from "express";
const unless = (middleware: Handler, ...paths: RegExp[]): Handler => {
return function (req: Request, res: Response, next: NextFunction) {
const pathCheck = paths.some(path => path.test(req.path));
pathCheck ? next() : middleware(req, res, next);
};
};
app.use(unless(redirectPage, new RegExp("/user/login"), new RegExp("/user/register")));

Express app.get given an array

I'm reading code from https://github.com/FrankHassanabad/Oauth2orizeRecipes which demonstrate the use of OAuth2orize, which can be used to implement OAuth2 authorization server.
The question I'm asking is nothing fancy though. I just have trouble with the basics of Express 3.x.
In app.js:
oauth2 = require('./oauth2')
. . .
app.get('/dialog/authorize', oauth2.authorization);
In Oauth2.js:
exports.authorization = [
login.ensureLoggedIn(),
server.authorization(function (clientID, redirectURI, scope, done) {
db.clients.findByClientId(clientID, function (err, client) {
if (err) {
return done(err);
}
if(client) {
client.scope = scope;
}
// WARNING: For security purposes, it is highly advisable to check that
// redirectURI provided by the client matches one registered with
// the server. For simplicity, this example does not. You have
// been warned.
return done(null, client, redirectURI);
});
}),
function (req, res, next) {
//Render the decision dialog if the client isn't a trusted client
//TODO Make a mechanism so that if this isn't a trusted client, the user can recorded that they have consented
//but also make a mechanism so that if the user revokes access to any of the clients then they will have to
//re-consent.
db.clients.findByClientId(req.query.client_id, function(err, client) {
if(!err && client && client.trustedClient && client.trustedClient === true) {
//This is how we short call the decision like the dialog below does
server.decision({loadTransaction: false}, function(req, callback) {
callback(null, { allow: true });
})(req, res, next);
} else {
res.render('dialog', { transactionID: req.oauth2.transactionID, user: req.user, client: req.oauth2.client });
}
});
}
];
So, is it because app.get() can take an array of middlewares? I'm trying to find where the code to app.get() is to figure out but I can't find it.
EDIT:
I'm on Express 3.6. So according to Infer-on's answer, correct me if I'm wrong.
You mean oauth2.authorization array instead of module?
app.VERB goes to this._router[method].apply(this._router, arguments);
where arguments is an array-like object with exactly one item, which is the oauth2.authorization array.
Then goes to router/index.js in the function defined by:
methods.forEach(function(method){
Router.prototype[method] = function(path){
var args = [method].concat([].slice.call(arguments));
this.route.apply(this, args);
return this;
};
});
Here, what previously was arguments is now path. And then becomes args. So the original array given by oauth2.authorization is still there and is an item inside args which has the length of 2, the first item is the method name "get" and the second is the array.
this.route is defined in the same file:
Router.prototype.route = function(method, path, callbacks){
var method = method.toLowerCase()
, callbacks = utils.flatten([].slice.call(arguments, 2));
// ensure path was given
if (!path) throw new Error('Router#' + method + '() requires a path');
// ensure all callbacks are functions
callbacks.forEach(function(fn){
if ('function' == typeof fn) return;
var type = {}.toString.call(fn);
var msg = '.' + method + '() requires callback functions but got a ' + type;
throw new Error(msg);
});
// create the route
debug('defined %s %s', method, path);
var route = new Route(method, path, callbacks, {
sensitive: this.caseSensitive,
strict: this.strict
});
// add it
(this.map[method] = this.map[method] || []).push(route);
return this;
};
Since there is utils.flatten([].slice.call(arguments, 2)); the array from oauth2.authorization gets flattened. So it's as if the things sent weren't array but normal arguments. (I don't know what the "2" is doing). The 3rd of the oauth2.authorization is the callback that's easy to understand. The first is login.ensureLoggedIn() which is a middleware? The second is server.authorization()..but I'm not entirely sure what it's doing.
for the get method, after the first argument, application will add the route, then will pass the other arguments to related controller
this._router[method].apply(this._router, arguments);
app.js
app.get('/', routes.index);
index.js
// controller
exports.index = function(req, res){
res.render('index', { title: 'Express' });
};
application.js
methods.forEach(function(method){
app[method] = function(path){
if ('get' == method && 1 == arguments.length) return this.set(path);
// deprecated
if (Array.isArray(path)) {
console.trace('passing an array to app.VERB() is deprecated and will be removed in 4.0');
}
// if no router attached yet, attach the router
if (!this._usedRouter) this.use(this.router);
// setup route
this._router[method].apply(this._router, arguments);
return this;
};
});
so
app.get('/dialog/authorize', oauth2.authorization);
for the /dialog/authorize view will be passed the authorization method exported by oauth2.authorization module
EDIT
I'm not sure of the array export, try something like Implement Authorization Endpoint:
app.get('/dialog/authorize',
login.ensureLoggedIn(),
server.authorization(function (clientID, redirectURI, scope, done) {
db.clients.findByClientId(clientID, function (err, client) {
if (err) {
return done(err);
}
if(client) {
client.scope = scope;
}
// WARNING: For security purposes, it is highly advisable to check that
// redirectURI provided by the client matches one registered with
// the server. For simplicity, this example does not. You have
// been warned.
return done(null, client, redirectURI);
});
}),
function (req, res, next) {
//Render the decision dialog if the client isn't a trusted client
//TODO Make a mechanism so that if this isn't a trusted client, the user can recorded that they have consented
//but also make a mechanism so that if the user revokes access to any of the clients then they will have to
//re-consent.
db.clients.findByClientId(req.query.client_id, function(err, client) {
if(!err && client && client.trustedClient && client.trustedClient === true) {
//This is how we short call the decision like the dialog below does
server.decision({loadTransaction: false}, function(req, callback) {
callback(null, { allow: true });
})(req, res, next);
} else {
res.render('dialog', { transactionID: req.oauth2.transactionID, user: req.user, client: req.oauth2.client });
}
});
});

how to get request path with express req object

I'm using express + node.js and I have a req object, the request in the browser is /account but when I log req.path I get '/' --- not '/account'.
//auth required or redirect
app.use('/account', function(req, res, next) {
console.log(req.path);
if ( !req.session.user ) {
res.redirect('/login?ref='+req.path);
} else {
next();
}
});
req.path is / when it should be /account ??
After having a bit of a play myself, you should use:
console.log(req.originalUrl)
Here is an example expanded from the documentation, which nicely wraps all you need to know about accessing the paths/URLs in all cases with express:
app.use('/admin', function (req, res, next) { // GET 'http://www.example.com/admin/new?a=b'
console.dir(req.originalUrl) // '/admin/new?a=b' (WARNING: beware query string)
console.dir(req.baseUrl) // '/admin'
console.dir(req.path) // '/new'
console.dir(req.baseUrl + req.path) // '/admin/new' (full path without query string)
next()
})
Based on: https://expressjs.com/en/api.html#req.originalUrl
Conclusion: As c1moore's answer states, use:
var fullPath = req.baseUrl + req.path;
In some cases you should use:
req.path
This gives you the path, instead of the complete requested URL. For example, if you are only interested in which page the user requested and not all kinds of parameters the url:
/myurl.htm?allkinds&ofparameters=true
req.path will give you:
/myurl.html
UPDATE 8 YEARS LATER:
req.path was already doing exactly same thing that I mentioned here. I don't remember how this answer solved issue and accepted as a correct answer but currently it's not a valid answer. Please ignore this answer. Thanks #mhodges for mentioning this.
Original answer:
If you want to really get only "path" without querystring, you can use url library to parse and get only path part of url.
var url = require('url');
//auth required or redirect
app.use('/account', function(req, res, next) {
var path = url.parse(req.url).pathname;
if ( !req.session.user ) {
res.redirect('/login?ref='+path);
} else {
next();
}
});
This can produce different results when calling directly in base module i.e. main file (e.g. index.js or app.js) vs calling from inside module via app.use() middleware i.e. route file (e.g. routes/users.js).
API call:
http://localhost:8000/api/users/profile/123/summary?view=grid&leng=en
We'll be comparing our outputs against above API call
1) First, we'll see the result from inside module:
We'll be placing our user module inside routes directory, with one route
routes/users.js
const router = (require('express')).Router();
router.get('/profile/:id/:details', (req, res) => {
console.log(req.protocol); // http or https
console.log(req.hostname); // only hostname (abc.com, localhost, etc)
console.log(req.headers.host); // hostname with port number (if any)
console.log(req.header('host')); // <same as above>
console.log(req.route.path); // exact defined route
console.log(req.baseUrl); // base path or group prefix
console.log(req.path); // relative path except path
console.log(req.url); // relative path with query|search params
console.log(req.originalUrl); // baseURL + url
// Full URL
console.log(`${req.protocol}://${req.header('host')}${req.originalUrl}`);
res.sendStatus(200);
});
module.exports = router;
index.js
const app = (require('express'))();
const users = require('./routes/users');
app.use('/api/users', users);
const server = require('http').createServer(app);
server.listen(8000, () => console.log('server listening'));
Output
http ....................................................................................... [protocol]
localhost .............................................................................. [hostname]
localhost:8000 ..................................................................... [headers.host]
localhost:8000 ..................................................................... [header('host')]
/profile/:id/:details ........................................................ [route.path]
/api/users ............................................................................. [baseUrl]
/profile/123/summary .......................................................... [path]
/profile/123/summary?view=grid&leng=en ........................ [url]
/api/users/profile/123/summary?view=grid&leng=en ..... [originalUrl]
Full URL:
http://localhost:8000/api/users/profile/123/summary?view=grid&leng=en
2) Now, directly from main module:
We'll define our route right in the starting file (i.e. app.js or index.js)
index.js
const app = (require('express'))();
app.get('/api/users/profile/:id/:details', (req, res) => {
console.log(req.protocol); // http or https
console.log(req.hostname); // only hostname (abc.com, localhost, etc)
console.log(req.headers.host); // hostname with port number (if any)
console.log(req.header('host')); // <same as above>
console.log(req.route.path); // exact defined route
console.log(req.baseUrl); // base path or group prefix
console.log(req.path); // relative path except path
console.log(req.url); // relative path with query|search params
console.log(req.originalUrl); // baseURL + url
// Full URL
console.log(`${req.protocol}://${req.header('host')}${req.originalUrl}`);
res.sendStatus(200);
});
const server = require('http').createServer(app);
server.listen(8000, () => console.log('server listening'));
Output
http ........................................................................ [protocol]
localhost ............................................................... [hostname]
localhost:8000 ...................................................... [headers.host]
localhost:8000 ...................................................... [header('host')]
/profile/:id/:details ......................................... [route.path]
.............................................................................. [baseUrl]
/profile/123/summary ........................................... [path]
/profile/123/summary?view=grid&leng=en ......... [url]
/profile/123/summary?view=grid&leng=en ......... [originalUrl]
Full URL:
http://localhost:8000/api/users/profile/123/summary?view=grid&leng=en
We can clearly see in above output that the only difference is of baseUrl which is empty string here. So, the originalUrl also changes & looks same as the url
//auth required or redirect
app.use('/account', function(req, res, next) {
console.log(req.path);
if ( !req.session.user ) {
res.redirect('/login?ref='+req.path);
} else {
next();
}
});
req.path is / when it should be /account ??
The reason for this is that Express subtracts the path your handler function is mounted on, which is '/account' in this case.
Why do they do this?
Because it makes it easier to reuse the handler function. You can make a handler function that does different things for req.path === '/' and req.path === '/goodbye' for example:
function sendGreeting(req, res, next) {
res.send(req.path == '/goodbye' ? 'Farewell!' : 'Hello there!')
}
Then you can mount it to multiple endpoints:
app.use('/world', sendGreeting)
app.use('/aliens', sendGreeting)
Giving:
/world ==> Hello there!
/world/goodbye ==> Farewell!
/aliens ==> Hello there!
/aliens/goodbye ==> Farewell!
It should be:
req.url
express 3.1.x
For version 4.x you can now use the req.baseUrl in addition to req.path to get the full path. For example, the OP would now do something like:
//auth required or redirect
app.use('/account', function(req, res, next) {
console.log(req.baseUrl + req.path); // => /account
if(!req.session.user) {
res.redirect('/login?ref=' + encodeURIComponent(req.baseUrl + req.path)); // => /login?ref=%2Faccount
} else {
next();
}
});
req.route.path is working for me
var pool = require('../db');
module.exports.get_plants = function(req, res) {
// to run a query we can acquire a client from the pool,
// run a query on the client, and then return the client to the pool
pool.connect(function(err, client, done) {
if (err) {
return console.error('error fetching client from pool', err);
}
client.query('SELECT * FROM plants', function(err, result) {
//call `done()` to release the client back to the pool
done();
if (err) {
return console.error('error running query', err);
}
console.log('A call to route: %s', req.route.path + '\nRequest type: ' + req.method.toLowerCase());
res.json(result);
});
});
};
after executing I see the following in the console and I get perfect result
in my browser.
Express server listening on port 3000 in development mode
A call to route: /plants
Request type: get
For those getting undefined from req.route.path that is correct.
Inside route handler, there's a route.
Inside middleware handlers, there's no route.
When using a middleware in express, your request object has several properties you can use to get the correct path:
req.baseUrl: /api/account
req.originalUrl: /api/account
req._parsedUrl.path: /account
req._parsedUrl.pathname: /account
req._parsedUrl.href: /account
req._parsedUrl._raw: /account
PLEASE NOTE: This applies to middlewares

Categories