Can I set a base URL for a NodeJS application?

I want to be able to host multiple NodeJS applications in the same domain without using subdomains (e.g. google.com/reader instead of images.google.com). The problem is that I always print the first part of the URL, for example. "/ reader" in Express / NodeJS.

How do I configure an Express application so that the base URL is something.com/myapp ?

So, instead of:

 app.get("/myapp", function (req, res) { // can be accessed from something.com/myapp }); 

I can do:

 // Some set-up app.base = "/myapp" app.get("/", function (req, res) { // can still be accessed from something.com/myapp }); 

I would also like to configure Connect staticProvider in the same way (now by default it serves to serve static files on something.com/js or something.com/css instead of something.com/myapp/js )

+45
express connect
Dec 07 '10 at 10:20
source share
7 answers

This is not currently supported, and it is not easy to add it yourself.

All routing information is buried deep inside the server code, and as a bonus there is no impact on the routes that they themselves.

I dug the source and also checked the latest version of Express and Connect middleware, but there is still no support for such features, you should open the problem either on Connect or Express .

In the same time...

Fix it yourself, here's a quick and easy way with changing just one line of code.

In ~/.local/lib/node/.npm/express/1.0.0/package/lib/express/servers.js do a search:

 // Generate the route this.routes[method](path, fn); 

This should be around line 357 , replace with:

 // Generate the route this.routes[method](((self.settings.base || '') + path), fn); 

Now just add a parameter:

 app.set('base', '/myapp'); 

This works great with paths that are straight strings, for RegEx support you will have to hack into the middleware of the router yourself, otherwise it is better to indicate the problem.

As for the static provider, just add /mypapp when configuring.

Update

Did the job with RegExp too:

 // replace this.routes[method](baseRoute(self.settings.base || '', path), fn); // helper function baseRoute(base, path) { if (path instanceof RegExp) { var exp = RegExp(path).toString().slice(1, -1); return new RegExp(exp[0] === '^' ? '^' + base + exp.substring(1) : base + exp); } else { return (base || '') + path; } } 

I tested this with just a few expressions, so this is not 100% tested, but theoretically it should work.

Update 2

Patch issue filed:
https://github.com/visionmedia/express/issues/issue/478

+14
Dec 07 '10 at 11:12
source share

Express router can handle this with 4.0

http://expressjs.com/api#router
http://bulkan-evcimen.com/using_express_router_instead_of_express_namespace.html

 var express = require('express'); var app = express(); var router = express.Router(); // simple logger for this router 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 ends in /bar 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); 



Previous answer (before express 4.0):

The express namespace module (now dead) is used to perform the trick:

https://github.com/visionmedia/express-namespace

 require('express-namespace'); app.namespace('/myapp', function() { app.get('/', function (req, res) { // can be accessed from something.com/myapp }); }); 
+100
May 13, '11 at 15:40
source share

I was able to achieve this using a combination of the namespace for routes and the fix from the google group discussion for static assets below. This snippet will handle the request /foo/javascripts/jquery.js as a request to /javascripts/jquery.js:

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

Source: https://groups.google.com/forum/#!msg/express-js/xlP6_DX6he0/6OTY4hwfV-0J

+5
Sep 18 '12 at 21:32
source share

Just update the stream, now with Express.js v4 you can do this without using express-namespace :

 var express = require('express'), forumRouter = express.Router(), threadRouter = express.Router(), app = express(); forumRouter.get('/:id)', function(req, res){ res.send('GET forum ' + req.params.id); }); forumRouter.get('/:id/edit', function(req, res){ res.send('GET forum ' + req.params.id + ' edit page'); }); forumRouter.delete('/:id', function(req, res){ res.send('DELETE forum ' + req.params.id); }); app.use('/forum', forumRouter); threadRouter.get('/:id/thread/:tid', function(req, res){ res.send('GET forum ' + req.params.id + ' thread ' + req.params.tid); }); forumRouter.use('/', threadRouter); app.listen(app.get("port") || 3000); 

Hurrah!

+5
Jul 14 '14 at 20:03
source share

There are also security issues. If reliability is important, a common solution is to use a reverse HTTP proxy server, such as nginx or HAProxy. They both use a single-threaded evented architecture and are therefore highly scalable.

Then you can have different node processes for different sub-sites, and if one site crashes (undetected exception, memory leak, programmer error, regardless), the remaining sub-sites continue to work.

+3
Sep 05 '11 at 19:20
source share

I was looking for this function, but for API routes, not static files. I did that when I initialized the router, I added the mount path. So my configuration is as follows:

 //Default configuration app.configure(function(){ app.use(express.compress()); app.use(express.logger('dev')); app.set('json spaces',0); app.use(express.limit('2mb')); app.use(express.bodyParser()); app.use('/api', app.router); // <--- app.use(function(err, req, res, callback){ res.json(err.code, {}); }); }); 

Pay attention to "/ api" when calling the router

+2
Apr 19 '13 at 13:10
source share

I know this is a very old question, but Express has changed a lot since most of these answers have been posted, so I decided to share my approach.

Of course, you can use Routers with Express 4 to group related functions along a specific path. This is well documented and already covered by other answers.

However, it is also possible to mount the whole application in a specific path. As an example, suppose our application (the one we want to place in /myapp ) looks like this: in a file called myapp.js :

 var express = require('express'), path = require('path'), app = express(); app.use(express.static(path.join(__dirname, 'public'))); app.get('/hello', function(req, res) { res.send('Hello'); }); // Lots of other stuff here exports.app = app; 

In our main js file, we could mount this entire application in the /myapp path:

 var express = require('express'), app = express(), myApp = require('./myapp').app; app.use('/myapp', myApp); app.listen(3000); 

Please note that here we have created two applications, one of which is mounted on the other. The main application may have additional sub-applications installed on different paths as needed.

The code in myapp.js completely independent of where it was installed. This is similar to the structure used by express-generator in this regard.

Some sub-application docs can be found here:

https://expressjs.com/en/4x/api.html#app.mountpath https://expressjs.com/en/4x/api.html#app.onmount

0
Sep 13 '17 at 20:59 on
source share



All Articles