How can I implement virtual directories with node.js and express? - node.js

I want to use the express static server configuration for implementing an static server:
app.configure(function() {
app.use(express.static(__dirname + '/public'));
});
But I want to map the URL http://myhost/url1 to directory C:\dirA\dirB and http://myhost/url2 to directory C:\dirC
How can it be implemented using express.static?

This should work for you:
var serveStatic = require( "serve-static" );
app.use('/url1', serveStatic('c:\\dirA\\dirB'));
app.use('/url2', serveStatic('C:\\dirC'));
Take a look at the documentation for app.use().

Depending on how many directories you're planning to map this way, you could simply make symlinks for those directories in your public folder.
In Windows:
mklink /D c:\dirA\dirB public\url1
In Linux or OSX:
ln -s /dirA/dirB public/url1
Then your static assets server should serve from those directories transparently (I've never tested on Windows but I don't see why it wouldn't work).
Alternatively, if you wanted to include some kind of dynamic routing, you could write your own middleware to replace express.static which is actually connect.static under the hood. Take a look at static.js in the connect source and see how it's implemented, it should be fairly straightforward to write your own variation.

Related

cannot reach a file on server though I exposed using express

In my project I need to store some text files dynamically and end user should be able to download them from browser. I know the best way is using object store like MINIO or S3 but unfortunately the only way I have is to use in memory storage. So what I am trying to do is: I made a public folder and I exposed it using the following code:
var express = require('express');
var app = express();
//setting middleware
app.use(express.static( 'public')); //Serves resources from public folder
var server = app.listen(5000);
it is as simple as that. Then for testing just to make sure I can download and reach a file I created a public folder with t.txt file in it and when I try:
http://localhost:5000/public/t.txt
I get
So why am I not getting it? Also is what I am trying to achieve will be a good match to scenario and is it doable at all?
When you're not specifying a path in app.use(), your app will serve the contents of the directory you're pointing to in express.static() on the root path. Try this:
http://localhost:5000/t.txt
That said, if you want it to be accessible at /public/t.txt, just specify the path:
app.use('/public', express.static('public'))
At first use the following line of code:
app.use(express.static(__dirname+'/public'));
This means that your home directory for static HTML pages is in the "public" folder. Note that the "__dirname" points to the directory of the current js file.
After that, call the following URL from the browser or POSTMAN:
http://localhost:5000/t.txt
As you can see, there is no need to write http://localhost:5000/public/t.txt referring to the "public" folder because you have already specified that in the app.use line.

nodejs express not to intercept messages for a folder with static content

I've a node, express system installed working on a host.
All requests are going through in the app.get('/path'... format
however in the domain I've html folder with static content that I want to serve
http://domain.com/html/attendee
http://domain.com/html/sponsors
and don't want node/express to intercept these requests and let them go through directly, not even serve through nodejs, otherwise relative linking problem.
Please suggest a solution.
You can't do it that way. node doesn't serve ANY content by default - it is not like some other web servers in that regard.
Instead, you specifically configure express to serve content from certain paths directly from the file system by inserting the right middleware commands early in the middleware stack.
For example, in one of my node apps, I use this middleware:
// static routes that get no further processing
app.use('/img', express.static(__dirname + '/img'));
app.use('/lib', express.static(__dirname + '/lib'));
This tells express that any content that starts with "/img" should be served directly from the appDirectory + "/img" directory. Same for elements in "/lib". One nice thing about this is that the paths you expose to the outside world do not have to be the same as the paths you use on your server and, in fact, by changing a few characters in your code, you can easily map to different directory.

Express/Connect: is it possible to use the static middleware several times?

I'm using Express and have my static files at a specific path and serve them trought static() middleware like that:
app.use(express.static(__dirname + '/public'));
I also use bower and used to configure a .bowerrc file to install stuff in that static used path.
I was wondering if I could not redefine a second static middleware like that:
app.use('/bower', express.static('/bower_components'));
So I get rid of my .bowerrc file.
But it's not working, is this sort of thing possible or am I completely misleading?
Yes, you absolutely can do that. If the first argument to use is a string, you're mounting the middleware to a specific URL path.
It's probably not working because you're specifying an absolute path for the static middleware – did you really mean bower_components under the root directory /?

Using nodejs Connect's static server middleware to serve only a subdirectory

I'm trying to build a webapp where:
http://mydomain.com/static/x.png serves x.png as a static file using Connect's static middleware
http://mydomain.com/other_stuff does other stuff
My directory structure is
start_server.coffee
static/
x.png
In start_server.coffee I have:
app = connect()
app.use connect.staticCache()
app.use connect.static(__dirname + '/static')
app.use ...middleware that serves the dynamic parts of my app...
app.listen 80
When I try http://mydomain.com/static/x.png, the request bypasses the static server and gets routed to the rest of my app. I stepped through the code in a debugger and it looks like static is trying to lookup static/static/x.png instead of static/x.png.
I was able to get it working by changing connect.static(_dirname + '/static') to connect.static(_dirname), but now it will serve stuff that's not in the static directory which is not good!
What's the cleanest way of doing what I'm trying to do? I could probably use Express's routing functionality, but I don't particularly want to use Express unless I have to, since the rest of my app handles routing its own way.
Thanks!
So the issue is the mismatch between your URL paths and your filesystem layout. There are 2 easy-peasy get-on-with-your-life solutions.
Remove "static/" from your URLs. The static middleware will only serve files under the static directory but the URLs won't include the word "static".
Do this: mkdir public && mv static public. Leave the public directory empty other than the static subdirectory. Now your URLs can stay the same and in your code you need app.use connect.static(__dirname + '/public').
Now this is what the static middleware provides out of the box. The URLs have to map simply to the filesystem. This is why it "just works" and is simple.
If you really want to have static/ in your URL but not map to a directory underneath your static root, add a middleware before the static middleware that alters req.path to remove the leading "/static", then call next() and I think that will trick the static middleware into doing what you want.

Is it possible to set the filesystem root and/or the document root to some subdirectory of the filesystem?

I would like to know if it is possible to specify a subdirectory for the filesystem root or the document root for requests of static resources (if there's any such distinction) in node.js.
I know that I can do it by concatenating an absolute path from the root, but I'm wondering if it can be done on an application-wide level.
I haven't found anything in the documentation supports it, but perhaps I'm overlooking it.
EDIT: I should mention that I'm not interested in using a 3rd party library at this point.
Check out expressjs
http://expressjs.com/guide.html#configuration
Specifically
app.use(express.static(__dirname + '/public', { maxAge: oneYear }));
Express/connect has a 'static' middleware for this use case. There are other smaller packages just for static file serving, however, express is nice and well maintained.
The API does not allow you to do what you're asking for directly. You will need to use string concat.
I've tried the following script with nodejs and works well. it takes the current path as document root to serve.
app.js
var http = require('http');
var express = require('express');
var app = express();
app.use(express.static('./'));
var server = http.createServer(app);
server.listen(8080,'127.0.0.1',function() {
console.log('listen to 127.0.0.1:8080');
});
the reference is here:
http://expressjs.com/starter/static-files.html

Resources