Express.js trying to set express.static with variables - node.js

I have template settings that vary depending on the subdomain I’m using. Therefore I’m trying to find a way to set the express.static dynamically based on the subdomain name I’m using.
When app.use runs, template is undefined. If I run app.use inside app.get it is out of scope. And if I try to run app.use from a function it is also out of scope.
"template" is a variable that I get in app.get it is my subdomain and http request
app.use('/subdomain/:domain/bower',express.static(path.join(__dirname, '/public/' + **template** + '/bower')));
app.get('/subdomain/:domain',function(req,res,next) {
get('/stores/template/' + req.params.domain)
.then(function(body){
console.log("template: " + body.toString());
template = body;
res.render('store',{store:req.params.domain});
});
});
I’m pretty sure it has to do with scopes, but so far I haven’t been able to solve it. Any help would be appreciated

Your first app.use() and the express.static() call in it runs when your sever is first starting up. At that point, the template variable does not yet have a value. You can't really do things the way you're trying to do it.
app.get() runs immediately also, but its callback is not called until sometime in the future when an http request matching that route actually arrives. By then, when the template variable gets assigned, it's way too late for it to be useful in your prior app.use() statement.
This would be much easier if your server could just know which sub-domain it was serving when it was originally set up from a configuration file or something like that. If you intend for the same server to serve many sub-domains at once and you want it to serve different files based on the subdomain, then you will have to code completely differently because you can't just use plain route matching like express.static() does since what you really want is sub-domain + route matching which isn't a built-in feature that I'm aware of.
I think if I was trying to solve this, I'd have my first middleware examine the sub-domain of the request and insert it into the front of the URL making a unique pseudo-URL for each sub-domain. Then, you could do normal routing on that pseudo-URL which is what the rest of the middleware and routes will see as the request URL.

Related

Unable to access ExpressJS route via href link

I'm not sure if this is a security feature or if I'm missing something obvious. I need to access one of my ExpressJS routes directly via a standard link on the page.
If I type the URL in to my browser location bar, I get the desired result. However, if I put that exact URL in a standard link on one of the pages on the site, the route never gets hit.
EDIT: Even if I pull this out of the router and add directly to app.js I get the same results. I'm simply trying to use Passport's Facebook authentication. The first route looks like this:
router.get('/login/facebook', function(req, res, next) {
passport.authenticate('facebook')(req, res, next);
});
I realize the req function wrapper is not needed, I was using it for debugging so I could see when the route gets called.
If I set a breakpoint there, it works fine if I just type the "/api/login/facebook" URL into my browser, but if I put the exact URL in a link on the page, the route never gets hit.
It turns out this was caused by Angular's routing mechanism intercepting the links. I found the solution here:
How to get Angular UI Router to respect "non-routed" URLs

Expose routes on different domains

I am struggling with something that doesn't look that hard : let's say I have 2 urls to access my server :
http://localhost:80/
and an external url
http://domain.com/internal/
Is there a way to do add a basepath internal if the forwarded host is equal to the external url host?
Something like :
app.use(function(req, res, next) {
if (req.headers['x-forwarded-host'] === 'domain.com') {
app.use('/internal', routes);
} else {
next();
}
})
There wont be any direct method as in a shortcut to work your way around for personal use cases.
I suggest this simple method though. Let's take example of app.get('/xyz') route.
This can be accessed locally via http://locahost:80/xyz or yourdomain.com/xyz via any application not hosted locally (Unless you make a call using your domainname in your own application).
Add a header element with every request when the call is internal.
Now, whenever our/xyz route is called check for that header element using a if condition and if the request is made internally you'll have that header element there and then you can simply use either res.redirect or any other method that you find useful (Exporting function in current route or anything else you find easy and needful).

Express static serving wrong path

I am messing around with express.js and have built some basic functionality but am having issues with express static serving from the wrong place if the URL is longer than one directory from root. See the examples below.
I am using the normal documented approach to using static.
app.use(express.static(__dirname + '/public'));
And have set up a couple of routes. eg.
app.get('/signup', function(req, res) {
res.render('signup.ejs');
});
With a 404 catch at the end of the chain.
app.get('*', function(req, res){
res.status(404).render('404');
});
If I hit page such as localhost:3000 or localhost:3000/login which are defined routes, all is well. Even if I hit an undefined route of localhost:3000/foo, I get the 404 rendered correctly with all images present.
However if I go one further and do something like localhost:3000/login/foo all the images are missing and I will get an error in the browsers console with the following address.
http://localhost:3000/login/img/site-brand.png
This happens the same on routes defined with more than one directory too.
I interpreted the docs on the express website that regardless of what was calling for the static image it would be served from the public directory in root, which contains a js, img, and css directories.
My questions are, what have I misinterpreted? and how do I get express to always serve relative to root?
I wrote the whole question then realised that when I had set up the src="" tags in my .ejs files I had used relative paths, not absolute. Rather than delete the question I decided to answer it and post it for others.
So instead of using src="img/my-image.png" it should be src="/img/my-image.png" The leading slash indicates that the request is relative to root not the path that is making the request.
Basic web development stuff there. I should have seen it first time out but its late, and I am cramming my head full of new frameworks which is in turn squeezing the more trivial stuff out of my small brain.

How to create href links in a view, pointing to Express routes?

I want to create href links inside my views, but I do not want to point to a static address. I want to dynamically create href urls based on routes.
Example:
// app.js:
app.get('/test', function testPage(req, res, next) {
// do something here
});
// inside view.html:
<a href="path('testPage')" /> // something similar
<a href="/test" /> I do NOT want this!
Am I missing something, or there is no way to do that easily?
I've searched and I found that app._router.stack has all routes. But they are just a plain ARRAY so they don't have any kind of id or smth! What I came up with, is a function that parses all routes (from stack), gets their name, which is set only if the function has a name (http://expressjs.com/4x/api.html#req.route) and then create an object with key (route name) -> path.
Then I can use this function (somehow) inside views to create paths, right?
Any better ideas?
Coming from PHP frameworks background, I am used to two way routes. However, from what I've seen in tutorials, people just use the static links. I think it has to do with the nature of Node.js web applications. Lots of them are SPAs, so you just build an API and then refer to it statically from the frontend application.
When researching this topic, I've came accross this little library called 2-way router which can be used with Express. I haven't experimented with it yet, but it might be useful to you.
EDIT: Tried to re-word my search and I've found similar thread about url generation and express route naming.
EDIT: You can also implement django-like routing.

nodejs express dynamic static folder based on route

I need to be able to have multiple static (public) folders which I can achieve using the following:
app.use(express.static(path.join(__dirname, '/routes/mymod1/public')));
app.use(express.static(path.join(__dirname, '/routes/mymod2/public')));
This merges the 2 folders so they appear as one, but the problem with this is if I have the same filename in both folders, then the last file will win.
What I would like to do instead, is to dynamically route the static requests based on the requested route.
For example a static request to /mymod1/test.html would be directed to /mymod1/public/test.html and requests to mymod2/test.html would be directed to /mymod2/public/test.html
Is this possible ??
When you use the express.static middleware it try to resolve the file (in mymod1) and send it back. If no file is found the next middleware is call and try to resolve in mymod2 so the only the first one should win.
If you want to add a route, you can precise it as first argument:
app.use('/mymod1', express.static('...'))

Resources