Express and Node.js Training from StrongLoop

4.x API

Application

express()

Create an express application.

var express = require('express');
var app = express();

app.get('/', function(req, res){
  res.send('hello world');
});

app.listen(3000);

Properties

app.locals

The app.locals object is a JavaScript object, and its properties are local variables within the application.

app.locals.title
// => 'My App'

app.locals.email
// => 'me@myapp.com'

Once set, the value of app.locals properties persist throughout the life of the application, in contrast with res.locals properties that are valid only for the lifetime of the request.

You can accesss local variables in templates rendered within the application. This is useful for providing helper functions to templates, as well as app-level data. Note, however, that you cannot access local variables in middleware.

app.locals.title = 'My App';
app.locals.strftime = require('strftime');
app.locals.email = 'me@myapp.com';

app.mountpath

The app.mountpath property is the path pattern(s) on which a sub app was mounted.

A sub app is an instance express which may be used for handling the request to a route.
var express = required('express');

var app = express(); // the main app
var admin = express(); // the sub app

admin.get('/', function (req, res) {
  console.log(admin.mountpath); // /admin
  res.send('Admin Homepage');
})

app.use('/admin', admin); // mount the sub app

It is similar to the baseUrl property of the req object, except req.baseUrl returns the matched URL path, instead of the matched pattern(s).

If a sub-app is mounted on multiple path patterns, app.mountpath returns the list of patterns it is mounted on, as shown in the following example.

var admin = express();

admin.get('/', function (req, res) {
  console.log(admin.mountpath); // [ '/adm*n', '/manager' ]
  res.send('Admin Homepage');
})

var secret = express();
secret.get('/', function (req, res) {
  console.log(secret.mountpath); // /secr*t
  res.send('Admin Secret');
});

admin.use('/secr*t', secret); // load the 'secret' router on '/secr*t', on the 'admin' sub app
app.use(['/adm*n', '/manager'], admin); // load the 'admin' router on '/adm*n' and '/manager', on the parent app

Events

app.on('mount', callback(parent))

The mount event is fired on a sub-app, when it is mounted on a parent app. The parent app is passed to the callback function.

var admin = express();

admin.on('mount', function (parent) {
  console.log('Admin Mounted');
  console.log(parent); // refers to the parent app
});

admin.get('/', function (req, res) {
  res.send('Admin Homepage');
});

app.use('/admin', admin);

Methods

app.all(path, callback [, callback ...])

This method is like the standard app.METHOD() methods, except it matches all HTTP verbs.

It's useful for mapping "global" logic for specific path prefixes or arbitrary matches. For example, if you put the following at the top of all other route definitions, it requires that all routes from that point on require authentication, and automatically load a user. Keep in mind that these callbacks do not have to act as end-points: loadUser can perform a task, then call next() to continue matching subsequent routes.

app.all('*', requireAuthentication, loadUser);

Or the equivalent:

app.all('*', requireAuthentication)
app.all('*', loadUser);

Another example is white-listed "global" functionality. The example is much like before, however it only restricts paths that start with "/api":

app.all('/api/*', requireAuthentication);

app.delete(path, callback [, callback ...])

Route HTTP DELETE requests to the specified path with the specified callback functions. For more information, see the routing guide.

You can provide multiple callback functions that behave just like middleware. The only exception is that these callbacks may invoke next('route') to bypass the remaining route callback(s). You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route.

app.delete('/', function (req, res) {
  res.send('DELETE request to homepage');
});

app.disable(name)

Set Boolean setting name to false, where name is one of the properties from the app settings table. Calling app.set('foo', false) for a Boolean property is the same as calling app.disable('foo').

For example:

app.disable('trust proxy');
app.get('trust proxy');
// => false

app.disabled(name)

Check if the Boolean setting name is disabled (false), where name is one of the properties from the app settings table.

app.disabled('trust proxy');
// => true

app.enable('trust proxy');
app.disabled('trust proxy');
// => false

app.enable(name)

Set Boolean setting name to true, where name is one of the properties from the app settings table. Calling app.set('foo', true) for a Boolean property is the same as calling app.enable('foo').

app.enable('trust proxy');
app.get('trust proxy');
// => true

app.enabled(name)

Check if setting name is enabled, where name is one of the properties from the app settings table.

app.enabled('trust proxy');
// => false

app.enable('trust proxy');
app.enabled('trust proxy');
// => true

app.engine(ext, callback)

Register the given template engine callback as ext.

By default, Express will require() the engine based on the file extension. For example, if you try to render a "foo.jade" file, Express invokes the following internally, and caches the require() on subsequent calls to increase performance.

app.engine('jade', require('jade').__express);

Use this method for engines that do not provide .__express out of the box, or if you wish to "map" a different extension to the template engine.

For example, to map the EJS template engine to ".html" files:

app.engine('html', require('ejs').renderFile);

In this case EJS provides a .renderFile() method with the same signature that Express expects: (path, options, callback), though note that it aliases this method as ejs.__express internally so if you're using ".ejs" extensions you don't need to do anything.

Some template engines do not follow this convention. The consolidate.js library maps Node template engines to follow this convention, so they work seemlessly with Express.

var engines = require('consolidate');
app.engine('haml', engines.haml);
app.engine('html', engines.hogan);

app.get(name)

Get the value of name app setting, where name is one of strings in the app settings table. For example:

app.get('title');
// => undefined

app.set('title', 'My Site');
app.get('title');
// => "My Site"

app.get(path, callback [, callback ...])

Route HTTP GET requests to the specified path with the specified callback functions. For more information, see the routing guide.

You can provide multiple callback functions that behave just like middleware. The only exception is that these callbacks may invoke next('route') to bypass the remaining route callback(s). You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route.

app.get('/', function (req, res) {
  res.send('GET request to homepage');
});

app.listen(port, [hostname], [backlog], [callback])

Bind and listen for connections on the given host and port. This method is identical to Node's http.Server.listen().

var express = require('express');
var app = express();
app.listen(3000);

The app returned by express() is in fact a JavaScript Function, designed to be passed to Node's HTTP servers as a callback to handle requests. This enables you to provide both HTTP and HTTPS versions of your app with the same code base easily, as the app does not inherit from these (it is simply a callback):

var express = require('express');
var https = require('https');
var http = require('http');
var app = express();

http.createServer(app).listen(80);
https.createServer(options, app).listen(443);

The app.listen() method is a convenience method for the following (for HTTP only):

app.listen = function() {
  var server = http.createServer(this);
  return server.listen.apply(server, arguments);
};

app.METHOD(path, callback [, callback ...])

Route an HTTP request, where METHOD is the HTTP method of the request, such as GET, PUT, POST, and so on, in lowercase. The corresponding routing methods are then app.get(), app.post(), app.put(), and so on. For more information, see the routing guide.

Express supports the following routing methods corresponding to HTTP methods: get, post, put, head, delete, options, trace, copy, lock, mkcol, move, purge, propfind, proppatch, unlock, report, mkactivity, checkout, merge, m-search, notify, subscribe, unsubscribe, patch, search, and connect.

To route methods which translate to invalid JavaScript variable names, use the bracket notation. For example, app['m-search']('/', function ....

You can provide multiple callback functions that behave just like middleware. The only exception is that these callbacks may invoke next('route') to bypass the remaining route callback(s). You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there is no reason to proceed with the current route.

The API documentation explicitly includes only the most popular HTTP methods app.get(), app.post(), app.put(), and app.delete() to provide a quick sense of how things work. Other methods like app.lock(), app.subscribe(), and so on, work in exactly the same way.

There is a special routing method, app.all(), which is not derived from any HTTP method. It is used for loading middleware at a path for all request methods.

In the following example, the handler will be executed for requests to "/secret" whether using GET, POST, PUT, DELETE, or any other HTTP request method.

app.all('/secret', function (req, res, next) {
  console.log('Accessing the secret section ...')
  next() // pass control to the next handler
})

app.param([name], callback)

Map logic to route parameters. For example, when :user is present in a route path, you may map user loading logic to automatically provide req.user to the route, or perform validations on the parameter input.

Note

  • Param callback functions are local to the router on which they are defined. They are not inherited by mounted apps or routers. Hence, param callbacks defined on app will be triggered only by route parameters defined on app routes.
  • A param callback will be called only once in a request-response cycle, even if the parameter is matched in multiple routes.
app.param('id', function (req, res, next, id) {
  console.log('CALLED ONLY ONCE');
  next();
})

app.get('/user/:id', function (req, res, next) {
  console.log('although this matches');
  next();
});

app.get('/user/:id', function (req, res) {
  console.log('and this matches too');
  res.end();
});

The following snippet illustrates how the callback is much like middleware, thus supporting async operations. However, it provides the additional value of the parameter (here named as id), derived from the corresponding parameter in the req.params object. An attempt to load the user is then performed, assigning req.user; otherwise an error is passed to next(err).

app.param('user', function(req, res, next, id){
  User.find(id, function(err, user){
    if (err) {
      next(err);
    } else if (user) {
      req.user = user;
      next();
    } else {
      next(new Error('failed to load user'));
    }
  });
});
app.param(callback) is deprecated as of v4.11.0.

Alternatively, you can pass only a callback, in which case you have the opportunity to alter the app.param() API. For example the express-params defines the following callback which allows you to restrict parameters to a given regular expression.

This example is a bit more advanced. It is checking if the second argument is a regular expression, returning the callback, which acts much like the "user" param example.

app.param(function(name, fn){
  if (fn instanceof RegExp) {
    return function(req, res, next, val){
      var captures;
      if (captures = fn.exec(String(val))) {
        req.params[name] = captures;
        next();
      } else {
        next('route');
      }
    }
  }
});

The method could now be used to effectively validate parameters (and optionally parse them to provide capture groups):

app.param('id', /^\d+$/);

app.get('/user/:id([0-9]+)', function(req, res){
  res.send('user ' + req.params.id);
});

app.param('range', /^(\w+)\.\.(\w+)?$/);

app.get('/range/:range(\\w+\\.\\.\\w+)', function(req, res){
  var range = req.params.range.split('..');
  res.send('from ' + range[0] + ' to ' + range[1]);
});

app.path()

Returns the canonical path of the app.

var app = express()
  , blog = express()
  , blogAdmin = express();

app.use('/blog', blog);
blog.use('/admin', blogAdmin);

console.log(app.path()); // ''
console.log(blog.path()); // '/blog'
console.log(blogAdmin.path()); // '/blog/admin'

The behavior of this method can become very complicated in complex cases of mounted apps, hence it is recommended to use req.baseUrl to get the canonical path of the app.

app.post(path, callback [, callback ...])

Route HTTP POST requests to the specified path with the specified callback functions. For more information, see the routing guide.

You can provide multiple callback functions that behave just like middleware. The only exception is that these callbacks may invoke next('route') to bypass the remaining route callback(s). You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route.

app.post('/', function (req, res) {
  res.send('POST request to homepage');
});

app.put(path, callback [, callback ...])

Route HTTP PUT requests to the specified path with the specified callback functions. For more information, see the routing guide.

You can provide multiple callback functions that behave just like middleware. The only exception is that these callbacks may invoke next('route') to bypass the remaining route callback(s). You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there's no reason to proceed with the current route.

app.put('/', function (req, res) {
  res.send('PUT request to homepage');
});

app.render(view, [locals], callback)

Return the rendered HTML of a view via the callback function. It accepts an optional object of local variables for the view. It is like res.render(), except it cannot send the rendered view to the client on its own.

Think of app.render() as a utility function for generating rendered view strings. Internally res.render() uses app.render() to render views.
The local variable cache is reserved for enabling view cache. Set it to true, if you want to cache view during development; view caching is enabled in production by default.
app.render('email', function(err, html){
  // ...
});

app.render('email', { name: 'Tobi' }, function(err, html){
  // ...
});

app.route(path)

Returns an instance of a single route, which can then be used to handle HTTP verbs with optional middleware. Using app.route() is a recommended approach for avoiding duplicate route names (and thus typo errors).

var app = express();

app.route('/events')
.all(function(req, res, next) {
  // runs for all HTTP verbs first
  // think of it as route specific middleware!
})
.get(function(req, res, next) {
  res.json(...);
})
.post(function(req, res, next) {
  // maybe add a new event...
})

app.set(name, value)

Assign setting name to value, where name is one of the properties from the app settings table.

Calling app.set('foo', true) for a Boolean property is the same as calling app.enable('foo'). Similarly, calling app.set('foo', false) for a Boolean property is the same as calling app.disable('foo').

Retrieve the value of a setting with app.get().

app.set('title', 'My Site');
app.get('title'); // "My Site"

Application Settings

If name is one of the application settings, it affects the behavior of the application. The following table lists application settings.

PropertyTypeValueDefault
case sensitive routing Boolean Enable case sensitivity. Disabled. Treats "/Foo" and "/foo" as the same.
env String Environment mode. process.env.NODE_ENV (NODE_ENV environment variable) or "development".
etag Varied

Set the ETag response header. For possible values, see the etag options table.

More about the HTTP ETag header.

jsonp callback name String Specifies the default JSONP callback name. ?callback=
json replacer String JSON replacer callback. null
json spaces Number When set, sends prettified JSON string indented with the specified amount of spaces. Disabled.
query parser String The query parser to use, either "simple" or "extended". The simple query parser is based on Node's native query parser, querystring. The extended query parser is based on qs. "extended"
strict routing Boolean Enable strict routing. Disabled. Treats "/foo" and "/foo/" as the same by the router.
subdomain offset Number The number of dot-separated parts of the host to remove to access subdomain. 2
trust proxy Varied

Indicates the app is behind a front-facing proxy, and to use the X-Forwarded-* headers to determine the connection and the IP address of the client. NOTE: X-Forwarded-* headers are easily spoofed and the detected IP addresses are unreliable.

trust proxy is disabled by default. When enabled, Express attempts to determine the IP address of the client connected through the front-facing proxy, or series of proxies. The req.ips property, then, contains an array of IP addresses the client is connected through. To enable it, use the values described in the trust proxy options table.

The trust proxy setting is implemented using the proxy-addr package. For more information, see its documentation.

Disabled.
views String or Array A directory or an array of directories for the application's views. If an array, the views are looked up in the order they occur in the array. "process.cwd() + '/views'"
view cache Boolean Enables view template compilation caching. true in production.
view engine String The default engine extension to use when omitted.
x-powered-by Boolean Enables the "X-Powered-By: Express" HTTP header. true
Options for trust proxy setting
TypeValue
Boolean

If true, the client's IP address is understood as the left-most entry in the X-Forwarded-* header.

If false, the app is understood as directly facing the Internet and the client's IP address is derived from req.connection.remoteAddress. This is the default setting.

IP addresses An IP address, subnet, or an array of IP addresses, and subnets to trust. The following is the list of pre-configured subnet names.
  • loopback - 127.0.0.1/8, ::1/128
  • linklocal - 169.254.0.0/16, fe80::/10
  • uniquelocal - 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7
Set IP addresses in any of the following ways:
app.set('trust proxy', 'loopback') // specify a single subnet
app.set('trust proxy', 'loopback, 123.123.123.123') // specify a subnet and an address
app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple subnets as CSV
app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array
When specified, the IP addresses or the subnets are excluded from the address determination process, and the untrusted IP address nearest to the application server is determined as the client's IP address.
Number Trust the nth hop from the front-facing proxy server as the client.
Function Custom trust implementation. Use this only if you know what you are doing.
app.set('trust proxy', function (ip) {
  if (ip === '127.0.0.1' || ip === '123.123.123.123') return true; // trusted IPs
  else return false;
})
Options for etag setting
TypeValue
Boolean true enables weak ETag. This is the default setting.
false disables ETag altogether.
String If "strong", enables strong ETag.
If "weak", enables weak ETag.
Function Custom ETag function implementation. Use this only if you know what you are doing.
app.set('etag', function (body, encoding) {
  return generateHash(body, encoding); // consider the function is defined
})

app.use([path,] function [, function...])

Mount the middleware function(s) at the path. If path is not specified, it defaults to "/".

A route will match any path, which follows its path immediately with a "/". For example: app.use('/apple', ...) will match /apple, /apple/images, /apple/images/news, and so on.

Mounting a middleware at a path will cause the middleware function to be executed whenever the base of the requested path matches the path.

Since path defaults to "/", middleware mounted without a path will be executed for every request to the app.

// this middleware will be executed for every request to the app
app.use(function (req, res, next) {
  console.log('Time: %d', Date.now());
  next();
})

Middleware functions are executed sequentially, therefore the order of middleware inclusion is important.

// this middleware will not allow the request to go beyond it
app.use(function(req, res, next) {
  res.send('Hello World');
})

// requests will never reach this route
app.get('/', function (req, res) {
  res.send('Welcome');
})

path can be a string representing a path, a path pattern, a regular expression to match paths, or an array of combinations of the aforementioned path objects.

The middleware in the below are simple examples.
Type Example
Path
// will match paths starting with /abcd
app.use('/abcd', function (req, res, next) {
  next();
})
Path Pattern
// will match paths starting with /abcd and /abd
app.use('/abc?d', function (req, res, next) {
  next();
})

// will match paths starting with /abcd, /abbcd, /abbbbbcd and so on
app.use('/ab+cd', function (req, res, next) {
  next();
})

// will match paths starting with /abcd, /abxcd, /abFOOcd, /abbArcd and so on
app.use('/ab*cd', function (req, res, next) {
  next();
})

// will match paths starting with /ad and /abcd
app.use('/a(bc)?d', function (req, res, next) {
  next();
})
Regular Expression
// will match paths starting with /abc and /xyz
app.use(/\/abc|\/xyz/, function (req, res, next) {
  next();
})
Array
// will match paths starting with /abcd, /xyza, /lmn, and /pqr
app.use(['/abcd', '/xyza', /\/lmn|\/pqr/], function (req, res, next) {
  next();
})

function can be a middleware function, a series of middleware functions, an array of middleware functions, or a combination of all of them. Since routers and apps implement the middleware interface, you can use them as you would any other middleware function.

Usage Example
Single Middleware You can define and mount a middleware function locally.
app.use(function (req, res, next) {
  next();
})
A router is valid middleware.
var router = express.Router();
router.get('/', function (req, res, next) {
  next();
})
app.use(router);
An Express app is valid middleware.
var subApp = express();
subApp.get('/', function (req, res, next) {
  next();
})
app.use(subApp);
Series of Middleware You can specify more than one middleware function at the same mount path.
var r1 = express.Router();
r1.get('/', function (req, res, next) {
  next();
})

var r2 = express.Router();
r2.get('/', function (req, res, next) {
  next();
})

app.use(r1, r2);
Array Use an array to group middleware logically. If you pass an array of middleware as the first or only middleware parameters, then you must specify the mount path.
var r1 = express.Router();
r1.get('/', function (req, res, next) {
  next();
})

var r2 = express.Router();
r2.get('/', function (req, res, next) {
  next();
})

app.use('/', [r1, r2]);
Combination You can combine all the above ways of mounting middleware.
function mw1(req, res, next) { next(); }
function mw2(req, res, next) { next(); }

var r1 = express.Router();
r1.get('/', function (req, res, next) { next(); });

var r2 = express.Router();
r2.get('/', function (req, res, next) { next(); });

var subApp = express();
subApp.get('/', function (req, res, next) { next(); });

app.use(mw1, [mw2, r1, r2], subApp);

Following are some examples of using the express.static middleware in an Express app.

Serve static content for the app from the "public" directory in the application directory:

// GET /style.css etc
app.use(express.static(__dirname + '/public'));

Mount the middleware at "/static" to serve static content only when their request path is prefixed with "/static":

// GET /static/style.css etc.
app.use('/static', express.static(__dirname + '/public'));

Disable logging for static content requests by loading the logger middleware after the static middleware:

app.use(express.static(__dirname + '/public'));
app.use(logger());

Serve static files from multiple directories, but give precedence to "./public" over the others:

app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/files'));
app.use(express.static(__dirname + '/uploads'));

Request

Properties

req.baseUrl

This property refers to the URL path, on which a router instance was mounted.

var greet = express.Router();

greet.get('/jp', function (req, res) {
  console.log(req.baseUrl); // /greet
  res.send('Konichiwa!');
});

app.use('/greet', greet); // load the router on '/greet'

Even if a path pattern or a set of path patterns were used to load the router, the matched string is returned as the baseUrl, instead of the pattern(s). In the following example, the greet router is loaded on two path patterns.

app.use(['/gre+t', '/hel{2}o'], greet); // load the router on '/gre+t' and '/hel{2}o'

When the request is made to /greet/jp, req.baseUrl will be equal to "/greet"; and when the request is made to /hello/jp, it will be equal to "/hello".

req.baseUrl is similar to the mountpath property of the app object, except app.mountpath returns the matched path pattern(s).

req.body

Contains the key-value pairs of data submitted in the request body. It is undefined by default, and is populated with the use of a body-parsing middleware such as body-parser and multer.

The example below shows the use of body-parsing middleware to populate req.body.

var app = require('express')();
var bodyParser = require('body-parser');
var multer = require('multer'); 

app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.use(multer()); // for parsing multipart/form-data

app.post('/', function (req, res) {

  console.log(req.body);
  res.json(req.body);

})

req.cookies

This object requires the cookieParser() middleware for use. It contains cookies sent by the user-agent. If no cookies are sent, it defaults to {}.

// Cookie: name=tj
req.cookies.name
// => "tj"

Please refer to cookie-parser for additional documentation or any issues and concerns.

req.fresh

Check if the request is "fresh" (i.e. whether the Last-Modified and/or the ETag still match).

req.fresh
// => true

Please refer to fresh for additional documentation or any issues and concerns.

req.hostname

Returns the hostname from the "Host" header field.

// Host: "example.com:3000"
req.hostname
// => "example.com"

req.ip

Return the remote address (or, if "trust proxy" is enabled, the upstream address).

req.ip
// => "127.0.0.1"

req.ips

When "trust proxy" is true, parse the "X-Forwarded-For" ip address list and return an array. Otherwise, an empty array is returned.

For example, if the value were "client, proxy1, proxy2", you would receive the array ["client", "proxy1", "proxy2"], where "proxy2" is the furthest down-stream.

req.originalUrl

This property is much like req.url; however, it retains the original request url, allowing you to rewrite req.url freely for internal routing purposes. For example, the "mounting" feature of app.use() will rewrite req.url to strip the mount point.

// GET /search?q=something
req.originalUrl
// => "/search?q=something"

req.params

This property is an object containing properties mapped to the named route "parameters". For example, if you have the route /user/:name, then the "name" property is available to you as req.params.name. This object defaults to {}.

// GET /user/tj
req.params.name
// => "tj"

When a regular expression is used for the route definition, capture groups are provided in the array using req.params[N], where N is the nth capture group. This rule is applied to unnamed wild-card matches with string routes such as /file/*:

// GET /file/javascripts/jquery.js
req.params[0]
// => "javascripts/jquery.js"

req.path

Returns the request URL pathname.

// example.com/users?sort=desc
req.path
// => "/users"

req.protocol

Return the protocol string "http" or "https" when requested with TLS. If the "trust proxy" setting is enabled, the "X-Forwarded-Proto" header field will be trusted. If you're running behind a reverse proxy that supplies https for you, this may be enabled.

req.protocol
// => "http"

req.query

This property is an object containing the parsed query-string, defaulting to {}.

// GET /search?q=tobi+ferret
req.query.q
// => "tobi ferret"

// GET /shoes?order=desc&shoe[color]=blue&shoe[type]=converse
req.query.order
// => "desc"

req.query.shoe.color
// => "blue"

req.query.shoe.type
// => "converse"

req.route

The currently matched Route.

app.get('/user/:id?', function userIdHandler(req, res) {
  console.log(req.route);
  res.send('GET');
})

Example output from the previous snippet:

{ path: '/user/:id?',
  stack:
   [ { handle: [Function: userIdHandler],
       name: 'userIdHandler',
       params: undefined,
       path: undefined,
       keys: [],
       regexp: /^\/?$/i,
       method: 'get' } ],
  methods: { get: true } }

req.secure

Check if a TLS connection is established. This is a short-hand for:

'https' == req.protocol;

req.signedCookies

This object requires the cookieParser(secret) middleware for use. It contains signed cookies sent by the user-agent, unsigned and ready for use. Signed cookies reside in a different object to show developer intent; otherwise, a malicious attack could be placed on req.cookie values (which are easy to spoof). Note that signing a cookie does not make it "hidden" or encrypted; this simply prevents tampering (because the secret used to sign is private). If no signed cookies are sent, it defaults to {}.

// Cookie: user=tobi.CP7AWaXDfAKIRfH49dQzKJx7sKzzSoPq7/AcBBRVwlI3
req.signedCookies.user
// => "tobi"

Please refer to cookie-parser for additional documentation or any issues and concerns.

req.stale

Check if the request is "stale" (i.e. the Last-Modified and/or ETag headers do not match).

req.stale
// => true

req.subdomains

Return subdomains as an array.

// Host: "tobi.ferrets.example.com"
req.subdomains
// => ["ferrets", "tobi"]

req.xhr

Check if the request was issued with the "X-Requested-With" header field set to "XMLHttpRequest" (jQuery etc).

req.xhr
// => true

Methods

req.accepts(types)

Check if the given types are acceptable, returning the best match when true, or else undefined (in which case you should respond with 406 "Not Acceptable").

The type value may be a single mime type string (such as "application/json"), the extension name such as "json", a comma-delimited list, or an array. When a list or array is given, the best match (if any) is returned.

// Accept: text/html
req.accepts('html');
// => "html"

// Accept: text/*, application/json
req.accepts('html');
// => "html"
req.accepts('text/html');
// => "text/html"
req.accepts('json, text');
// => "json"
req.accepts('application/json');
// => "application/json"

// Accept: text/*, application/json
req.accepts('image/png');
req.accepts('png');
// => undefined

// Accept: text/*;q=.5, application/json
req.accepts(['html', 'json']);
req.accepts('html, json');
// => "json"

Please refer to accepts for additional documentation or any issues and concerns.

req.acceptsCharsets(charset, ...)

Check if the given charset are acceptable.

Please refer to accepts for additional documentation or any issues and concerns.

req.acceptsEncodings(encoding, ...)

Check if the given encoding are acceptable.

Please refer to accepts for additional documentation or any issues and concerns.

req.acceptsLanguages(lang, ...)

Check if the given lang are acceptable.

Please refer to accepts for additional documentation or any issues and concerns.

req.get(field)

Get the case-insensitive request header field. The Referrer and Referer fields are interchangeable.

req.get('Content-Type');
// => "text/plain"

req.get('content-type');
// => "text/plain"

req.get('Something');
// => undefined

Aliased as req.header(field).

req.is(type)

Check if the incoming request contains the "Content-Type" header field, and if it matches the give mime type.

// With Content-Type: text/html; charset=utf-8
req.is('html');
req.is('text/html');
req.is('text/*');
// => true

// When Content-Type is application/json
req.is('json');
req.is('application/json');
req.is('application/*');
// => true

req.is('html');
// => false

Please refer to type-is for additional documentation or any issues and concerns.

req.param(name, [defaultValue])

Deprecated. Use either req.params, req.body or req.query, as applicable.

Return the value of param name when present.

// ?name=tobi
req.param('name')
// => "tobi"

// POST name=tobi
req.param('name')
// => "tobi"

// /user/tobi for /user/:name 
req.param('name')
// => "tobi"

Lookup is performed in the following order:

  • req.params
  • req.body
  • req.query

Optionally, you can specify defaultValue to set a default value if the parameter is not found in any of the request objects.

Direct access to req.body, req.params, and req.query should be favoured for clarity - unless you truly accept input from each object. Body-parsing middleware must be loaded for req.param() to work predictably. Refer req.body for details.

Response

Properties

res.headersSent

Property indicating if HTTP headers has been sent for the response.

app.get('/', function (req, res) {
  console.log(res.headersSent); // false
  res.send('OK');
  console.log(res.headersSent); // true
})

res.locals

Response local variables are scoped to the request, and therefore only available to the view(s) rendered during that request / response cycle (if any). Otherwise, this API is identical to app.locals.

This object is useful for exposing request-level information such as the request pathname, authenticated user, user settings etc.

app.use(function(req, res, next){
  res.locals.user = req.user;
  res.locals.authenticated = ! req.user.anonymous;
  next();
});

Methods

res.append(field, [value])

res.append() is supported from Express v4.11.0 onwards

Append additional value value to an existing header named field; or create the header with the value value, if the header is not already set. value can be a string or an array of values to be appended.

Note that, calling res.set() after res.append() will reset the previously set header value.

res.append('Link', ['<http://localhost/>', '<http://localhost:3000/>']);
res.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly');
res.append('Warning', '199 Miscellaneous warning');

res.attachment([filename])

Sets the Content-Disposition header field to "attachment". If a filename is given, then the Content-Type will be automatically set based on the extname via res.type(), and the Content-Disposition's "filename=" parameter will be set.

res.attachment();
// Content-Disposition: attachment

res.attachment('path/to/logo.png');
// Content-Disposition: attachment; filename="logo.png"
// Content-Type: image/png

res.cookie(name, value, [options])

Set cookie name to value, which may be a string or object converted to JSON. The options object can have the following properties.

Property Description
domain Domain name for the cookie. Defaults to the domain name of the app.
path Path for the cookie. Defaults to "/".
secure Marks the cookie to be used with HTTPS only.
expires Expiry date of the cookie in GMT. If not specified or set to 0, creates a session cookie.
maxAge Convenient option for setting the expiry time relative to the current time in milliseconds.
httpOnly Flags the cookie to be accessible only by the web server.
signed Indicates if the cookie should be signed.
All res.cookie() does is set the HTTP Set-Cookie header with the options provided, any option which is not passed defaults to the behavior as specified in RFC 6265.

The following are some examples of setting cookie with various options.

res.cookie('name', 'tobi', { domain: '.example.com', path: '/admin', secure: true });
res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });

The maxAge option is a convenience option for setting "expires" relative to the current time in milliseconds. The following is equivalent to the previous example.

res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })

An object may be passed which is then serialized as JSON, which is automatically parsed by the bodyParser() middleware.

res.cookie('cart', { items: [1,2,3] });
res.cookie('cart', { items: [1,2,3] }, { maxAge: 900000 });

Signed cookies are also supported through this method. Simply pass the signed option. When given res.cookie() will use the secret passed to cookieParser(secret) to sign the value.

res.cookie('name', 'tobi', { signed: true });

Later you may access this value through the req.signedCookie object.

res.clearCookie(name, [options])

Clear cookie name. For details about the options object, refer res.cookie().

res.cookie('name', 'tobi', { path: '/admin' });
res.clearCookie('name', { path: '/admin' });

res.download(path, [filename], [fn])

Transfer the file at path as an "attachment". Typically, browsers will prompt the user for download. The Content-Disposition "filename=" parameter (i.e. the one that will appear in the brower dialog) is set to path by default. However, you may provide an override filename.

When an error has ocurred or transfer is complete the optional callback fn is invoked. This method uses res.sendFile() to transfer the file.

res.download('/report-12345.pdf');

res.download('/report-12345.pdf', 'report.pdf');

res.download('/report-12345.pdf', 'report.pdf', function(err){
  if (err) {
    // handle error, keep in mind the response may be partially-sent
    // so check res.headersSent
  } else {
    // decrement a download credit etc
  }
});

res.end([data], [encoding])

Inherited from node's http.ServerResponse, ends the response process. The only recommended use is for quickly ending the response without any data. If you need to respond with data, use Express' response methods such as res.send(), res.json() etc.

res.end();
res.status(404).end();

res.format(object)

Performs content-negotiation on the Accept HTTP header on the request object, when present. It uses req.accepts() to select a handler for the request, based on the acceptable types ordered by their quality values. If the header is not specified, the first callback is invoked. When no match is found, the server responds with 406 "Not Acceptable", or invokes the default callback.

The Content-Type response header is set for you when a callback is selected. However, you may alter this within the callback using res.set() or res.type() etcetera.

The following example would respond with { "message": "hey" } when the Accept header field is set to "application/json" or "*/json" (however if "*/*" is given, then "hey" will be the response).

res.format({
  'text/plain': function(){
    res.send('hey');
  },

  'text/html': function(){
    res.send('<p>hey</p>');
  },

  'application/json': function(){
    res.send({ message: 'hey' });
  },

  'default': function() {
    // log the request and respond with 406
    res.status(406).send('Not Acceptable');
  }
});

In addition to canonicalized MIME types, you may also use extension names mapped to these types for a slightly less verbose implementation:

res.format({
  text: function(){
    res.send('hey');
  },

  html: function(){
    res.send('<p>hey</p>');
  },

  json: function(){
    res.send({ message: 'hey' });
  }
});

res.get(field)

Get the case-insensitive response header field.

res.get('Content-Type');
// => "text/plain"

res.json([body])

Send a JSON response. This method is identical to res.send() when an object or array is passed. However, it may be used for explicit JSON conversion of non-objects, such as null, undefined, etc. (although these are technically not valid JSON).

res.json(null)
res.json({ user: 'tobi' })
res.status(500).json({ error: 'message' })

res.jsonp([body])

Send a JSON response with JSONP support. This method is identical to res.json(), except that it opts-in to JSONP callback support.

res.jsonp(null)
// => null

res.jsonp({ user: 'tobi' })
// => { "user": "tobi" }

res.status(500).jsonp({ error: 'message' })
// => { "error": "message" }

By default, the JSONP callback name is simply callback. However, you may alter this with the jsonp callback name setting. The following are some examples of JSONP responses using the same code:

// ?callback=foo
res.jsonp({ user: 'tobi' })
// => foo({ "user": "tobi" })

app.set('jsonp callback name', 'cb');

// ?cb=foo
res.status(500).jsonp({ error: 'message' })
// => foo({ "error": "message" })

Join the given links to populate the "Link" response header field.

res.links({
  next: 'http://api.example.com/users?page=2',
  last: 'http://api.example.com/users?page=5'
});

yields:

Link: &lt;http://api.example.com/users?page=2&gt;; rel="next", 
      &lt;http://api.example.com/users?page=5&gt;; rel="last"

res.location

Set the location header.

res.location('/foo/bar');
res.location('foo/bar');
res.location('http://example.com');
res.location('../login');
res.location('back');

You can use the same kind of urls as in res.redirect().

For example, if your application is mounted at /blog, the following would set the location header to /blog/admin:

res.location('admin')

res.redirect([status], url)

Express passes the specified URL string as-is to the browser in the Location header, without any validation or manipulation, except in case of back.

Browsers take the responsibility of deriving the intended URL from the current URL or the referring URL, and the URL specified in the Location header; and redirect the user accordingly.

Redirect to the given url with optional status code defaulting to 302 "Found".

res.redirect('/foo/bar');
res.redirect('http://example.com');
res.redirect(301, 'http://example.com');
res.redirect('../login');

Redirects can be a fully qualified URI for redirecting to a different site:

res.redirect('http://google.com');

Redirects can be relative to the root of the host name. For example, if you were on http://example.com/admin/post/new, the following redirect to /admin would land you at http://example.com/admin:

res.redirect('/admin');

Redirects can be relative to the current URL. A redirection of post/new, from http://example.com/blog/admin/ (notice the trailing slash), would give you http://example.com/blog/admin/post/new.

res.redirect('post/new');

Redirecting to post/new from http://example.com/blog/admin (no trailing slash), will take you to http://example.com/blog/post/new.

If you found the above behavior confusing, think of path segments as directories (have trailing slashes) and files, it will start to make sense.

Pathname relative redirects are also possible. If you were on http://example.com/admin/post/new, the following redirect would land you at http//example.com/admin/post:

res.redirect('..');

A back redirection will redirect the request back to the Referer (or Referrer), defaulting to / when missing.

res.redirect('back');

res.render(view, [locals], callback)

Render a view and send the rendered HTML string to the client. It accepts an optional object of local variables for the view. When a callback is provided both the possible error and rendered string are returned, and no automated response is performed. When an error occurs next(err) is invoked internally.

The local variable cache is reserved for enabling view cache. Set it to true, if you want to cache view during development; view caching is enabled in production by default.
// send the rendered view to the client
res.render('index');

// if a callback is specified, the rendered HTML string has to be sent explicitly
res.render('index', function(err, html) {
  res.send(html);
});

// pass a local variable to the view
res.render('user', { name: 'Tobi' }, function(err, html) {
  // ...
});

res.send([body])

Send a response.

res.send(new Buffer('whoop'));
res.send({ some: 'json' });
res.send('<p>some html</p>');
res.status(404).send('Sorry, we cannot find that!');
res.status(500).send({ error: 'something blew up' });

This method performs a myriad of useful tasks for simple non-streaming responses such as automatically assigning the Content-Length unless previously defined and providing automatic HEAD and HTTP cache freshness support.

When a Buffer is given the Content-Type is set to "application/octet-stream" unless previously defined as shown below:

res.set('Content-Type', 'text/html');
res.send(new Buffer('<p>some html</p>'));

When a String is given the Content-Type is set defaulted to "text/html":

res.send('<p>some html</p>');

When an Array or Object is given Express will respond with the JSON representation:

res.send({ user: 'tobi' });
res.send([1,2,3]);

res.sendFile(path, [options], [fn])

res.sendFile() is supported from Express v4.8.0 onwards

Transfer the file at the given path. The Content-Type response header field is automatically set based on the filename's extension. Unless the root option is set in the options object, path must be an absolute path of the file.

The details of the options object is listed in the following table.

Property Description Default Availability
maxAge Sets the max-age property of the Cache-Control header in milliseconds or a string in ms format 0
root Root directory for relative filenames.
lastModified Sets the Last-Modified header to the last modified date of the file on the OS. Set false to disable it. Enabled 4.9.0+
headers Object of HTTP headers to serve with the file.
dotfiles Option for serving dotfiles. Possible values are "allow", "deny", "ignore". "ignore"

The callback fn(err) is invoked when the transfer is complete or when an error occurs. If the callback function is specified and an error occurs, the response process must be handled explicitly within the callback function by either ending the request response cycle, or passing the control to the next route.

Here is an example of using res.sendFile with all its arguments.

app.get('/file/:name', function (req, res, next) {

  var options = {
    root: __dirname + '/public/',
    dotfiles: 'deny',
    headers: {
        'x-timestamp': Date.now(),
        'x-sent': true
    }
  };

  var fileName = req.params.name;
  res.sendFile(fileName, options, function (err) {
    if (err) {
      console.log(err);
      res.status(err.status).end();
    }
    else {
      console.log('Sent:', fileName);
    }
  });

})

res.sendFile provides fine-grained support for file serving as illustrated in the following example:

app.get('/user/:uid/photos/:file', function(req, res){
  var uid = req.params.uid
    , file = req.params.file;

  req.user.mayViewFilesFrom(uid, function(yes){
    if (yes) {
      res.sendFile('/uploads/' + uid + '/' + file);
    } else {
      res.status(403).send('Sorry! you cant see that.');
    }
  });
});

Please refer to send for additional documentation or any issues and concerns.

res.sendStatus(statusCode)

Set the response HTTP status code to statusCode and send its string representation as the response body.

res.sendStatus(200); // equivalent to res.status(200).send('OK')
res.sendStatus(403); // equivalent to res.status(403).send('Forbidden')
res.sendStatus(404); // equivalent to res.status(404).send('Not Found')
res.sendStatus(500); // equivalent to res.status(500).send('Internal Server Error')

If an unsupported status code is specified, the HTTP status is still set to statusCode and the string version of the code is sent as the response body.

res.sendStatus(2000); // equivalent to res.status(2000).send('2000')

More about HTTP Status Codes

res.set(field, [value])

Set header field to value, or pass an object to set multiple fields at once.

res.set('Content-Type', 'text/plain');

res.set({
  'Content-Type': 'text/plain',
  'Content-Length': '123',
  'ETag': '12345'
})

Aliased as res.header(field, [value]).

res.status(code)

Chainable alias of node's res.statusCode. Use this method to set the HTTP status for the response.

res.status(403).end();
res.status(400).send('Bad Request');
res.status(404).sendFile('/absolute/path/to/404.png');

res.type(type)

Sets the Content-Type to the mime lookup of type, or when "/" is present the Content-Type is simply set to this literal value.

res.type('.html');
res.type('html');
res.type('json');
res.type('application/json');
res.type('png');

res.vary(field)

Adds the field to the Vary response header, if it is not there already.

res.vary('User-Agent').render('docs');

Router

Router([options])

A router is an isolated instance of middleware and routes. Routers can be thought of as "mini" applications, capable only of performing middleware and routing functions. Every express application has a built-in app router.

Routers behave like middleware themselves and can be ".use()'d" by the app or in other routers.

Create a new router with express.Router():

var router = express.Router([options]);

options is an optional object to alter the behavior of the router.

Property Description Default Availability
caseSensitive Enable case sensitivity. Disabled by default, treating "/Foo" and "/foo" as the same.
strict Enable strict routing. Disabled by default, "/foo" and "/foo/" are treated the same by the router.
mergeParams Ensure the req.params values from the parent router are preserved. If the parent and the child have conflicting param names, the child's value take precedence. false 4.5.0+

The router can have middleware and http VERB routes added just like an application.

// invoked for any requests passed to this router
router.use(function(req, res, next) {
  // .. some logic here .. like any other middleware
  next();
});

// will handle any request that ends in /events
// depends on where the router is "use()'d"
router.get('/events', function(req, res, next) {
  // ..
});

You can then use a router for a particular root url in this way separating your routes into files or even mini apps.

// only requests to /calendar/* will be sent to our "router"
app.use('/calendar', router);

Methods

router.all(path, [callback...], callback)

This method functions just like the router.METHOD() methods, except that it matches all HTTP verbs.

This method is extremely useful for mapping "global" logic for specific path prefixes or arbitrary matches. For example, if you placed the following route at the top of all other route definitions, it would require that all routes from that point on would require authentication, and automatically load a user. Keep in mind that these callbacks do not have to act as end points; loadUser can perform a task, then next() to continue matching subsequent routes.

router.all('*', requireAuthentication, loadUser);

Or the equivalent:

router.all('*', requireAuthentication)
router.all('*', loadUser);

Another great example of this is white-listed "global" functionality. Here the example is much like before, but it only restricts paths prefixed with "/api":

router.all('/api/*', requireAuthentication);

router.METHOD(path, [callback...], callback)

The router.METHOD() methods provide the routing functionality in Express, where METHOD is one of the HTTP verbs, such as router.post(). Multiple callbacks may be given, all are treated equally, and behave just like middleware, with the one exception that these callbacks may invoke next('route') to bypass the remaining route callback(s). This mechanism can be used to perform pre-conditions on a route then pass control to subsequent routes when there is no reason to proceed with the route matched.

The following snippet illustrates the most simple route definition possible. Express translates the path strings to regular expressions, used internally to match incoming requests. Query strings are not considered when peforming these matches, for example "GET /" would match the following route, as would "GET /?name=tobi".

router.get('/', function(req, res){
  res.send('hello world');
});

Regular expressions may also be used, and can be useful if you have very specific restraints, for example the following would match "GET /commits/71dbb9c" as well as "GET /commits/71dbb9c..4c084f9".

router.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/, function(req, res){
  var from = req.params[0];
  var to = req.params[1] || 'HEAD';
  res.send('commit range ' + from + '..' + to);
});

router.param([name], callback)

Map logic to route parameters. For example, when :user is present in a route path you may map user loading logic to automatically provide req.user to the route, or perform validations on the parameter input.

Note

  • Param callback functions are local to the router on which they are defined. They are not inherited by mounted apps or routers. Hence, param callbacks defined on router will be trigerred only by route parameters defined on router routes.

  • A param callback will be called only once in a request-response cycle, even if the parameter is matched in multiple routes.

    router.param('id', function (req, res, next, id) {
      console.log('CALLED ONLY ONCE');
      next();
    })
    
    router.get('/user/:id', function (req, res, next) {
      console.log('although this matches');
      next();
    });
    
    router.get('/user/:id', function (req, res) {
      console.log('and this matches too');
      res.end();
    });
    

    The following snippet illustrates how the callback is much like middleware, thus supporting async operations. However, it provides the additional value of the parameter (here named as id), derived from the corresponding parameter in the req.params object. An attempt to load the user is then performed, assigning req.user, otherwise passing an error to next(err).

It is important to realize that any route that triggered a named parameter function to run will only be run if next was not called with an error in the named parameter handler.

router.param('user', function(req, res, next, id){
  User.find(id, function(err, user){
    if (err) {
      return next(err);
    }
    else if (!user) {
      return next(new Error('failed to load user'));
    }

    req.user = user;
    next();
  });
});

// this route uses the ":user" named parameter
// which will cause the 'user' param callback to be triggered
router.get('/users/:user', function(req, res, next) {
  // req.user WILL be defined here
  // if there was an error, normal error handling will be triggered
  // and this function will NOT execute
});

Alternatively you may pass only a callback, in which case you have the opportunity to alter the router.param() API. For example the express-params defines the following callback which allows you to restrict parameters to a given regular expression.

This example is a bit more advanced. It checks whether the second argument is a regular expression, returning the callback (which acts much like the "user" param example).

router.param(function(name, fn){
  if (fn instanceof RegExp) {
    return function(req, res, next, val){
      var captures;
      if (captures = fn.exec(String(val))) {
        req.params[name] = captures;
        next();
      } else {
        next('route');
      }
    }
  }
});

The method could now be used to effectively validate parameters (and optionally parse them to provide capture groups):

router.param('id', /^\d+$/);

router.get('/user/:id', function(req, res){
  res.send('user ' + req.params.id);
});

router.param('range', /^(\w+)\.\.(\w+)?$/);

router.get('/range/:range', function(req, res){
  var range = req.params.range;
  res.send('from ' + range[1] + ' to ' + range[2]);
});

The router.use() method also supports named parameters so that your mount points for other routers can benefit from preloading using named parameters.

router.route(path)

Returns an instance of a single route which can then be used to handle HTTP verbs with optional middleware. Using router.route() is a recommended approach to avoiding duplicate route naming and thus typo errors.

Building on the router.param() example from before, we see how router.route() allows us to easily specify the various HTTP verb handlers.

var router = express.Router();

router.param('user_id', function(req, res, next, id) {
  // sample user, would actually fetch from DB, etc...
  req.user = {
    id: id,
    name: 'TJ'
  };
  next();
});

router.route('/users/:user_id')
.all(function(req, res, next) {
  // runs for all HTTP verbs first
  // think of it as route specific middleware!
  next();
})
.get(function(req, res, next) {
  res.json(req.user);
})
.put(function(req, res, next) {
  // just an example of maybe updating the user
  req.user.name = req.params.name;
  // save user ... etc
  res.json(req.user);
})
.post(function(req, res, next) {
  next(new Error('not implemented'));
})
.delete(function(req, res, next) {
  next(new Error('not implemented'));
})

This apporach re-uses the single '/users/:user_id' path and add handlers for the various HTTP verbs.

router.use([path], [function...], function)

The interface is similar to app.use(). A simple example and usecase is described below, read the app.use() documentation for the details.

Use the given middleware function, with optional mount path, defaulting to "/".

Middleware is like a plumbing pipe, requests start at the first middleware you define and work their way "down" the middleware stack processing for each path they match.

var express = require('express');
var app = express();
var router = express.Router();

// simple logger for this router's requests
// all requests to this router will first hit this middleware
router.use(function(req, res, next) {
  console.log('%s %s %s', req.method, req.url, req.path);
  next();
});

// this will only be invoked if the path starts with /bar from the mount point
router.use('/bar', function(req, res, next) {
  // ... maybe some additional /bar logging ...
  next();
});

// always invoked
router.use(function(req, res, next) {
  res.send('Hello World');
});

app.use('/foo', router);

app.listen(3000);

The "mount" path is stripped and is not visible to the middleware function. The main effect of this feature is that mounted middleware may operate without code changes regardless of its "prefix" pathname.

The order of which middleware are "defined" using router.use() is very important, they are invoked sequentially, thus this defines middleware precedence. For example usually a logger is the very first middleware you would use, logging every request:

var logger = require('morgan');

router.use(logger());
router.use(express.static(__dirname + '/public'));
router.use(function(req, res){
  res.send('Hello');
});

Now suppose you wanted to ignore logging requests for static files, but to continue logging routes and middleware defined after logger(), you would simply move static() above:

router.use(express.static(__dirname + '/public'));
router.use(logger());
router.use(function(req, res){
  res.send('Hello');
});

Another concrete example would be serving files from multiple directories, giving precedence to "./public" over the others:

app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/files'));
app.use(express.static(__dirname + '/uploads'));