Loading static files (with expressjs)

494 views
Skip to first unread message

drk

unread,
Jan 21, 2012, 4:41:27 PM1/21/12
to nodejs
Hi, I'm trying to load static files (in a separate folder) with
expressjs/nodejs.

I have (simplified):

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

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

app.listen(3000);


which loads the index.html file, but not the linked .css and .js
files.

I'm linking like (in the index.html):

<link type="text/css" rel="stylesheet" href="./css/basic.css" />

but it doesn't use the correct link.

Instead of,
localhost:3000/home/css/basic.css

it tries:

localhost:3000/css/basic.css

which doesn't exist.

Ryan Schmidt

unread,
Jan 21, 2012, 8:40:29 PM1/21/12
to nod...@googlegroups.com


What URL are you accessing?

If http://localhost:3000/ or http://localhost:3000/index.html then that sounds entirely expected.

If http://localhost:3000/home/ or http://localhost:3000/home/index.html then it should be working correctly, assuming you've set up a route to serve /home/ and/or /home/index.html.

drk

unread,
Jan 21, 2012, 9:58:49 PM1/21/12
to nodejs
aah!.. I was writing localhost:3000/home, which loads only the
index.html file.

but by writing localhost:3000/home/ it loads everything!

Why does writing localhost:3000/home just loads the html file?

On Jan 22, 1:40 am, Ryan Schmidt <google-2...@ryandesign.com> wrote:
> On Jan 21, 2012, at 15:41, drk wrote:
>
>
>
>
>
>
>
>
>
> > Hi, I'm trying to load static files (in a separate folder) with
> > expressjs/nodejs.
>
> > I have (simplified):
>
> > var express = require('express');
> > var app = express.createServer();
>
> > app.use('/home', express.static(__dirname + '/home'));
>
> > app.listen(3000);
>
> > which loads the index.html file, but not the linked .css and .js
> > files.
>
> > I'm linking like (in the index.html):
>
> > <link type="text/css" rel="stylesheet" href="./css/basic.css" />
>
> > but it doesn't use the correct link.
>
> > Instead of,
> >    localhost:3000/home/css/basic.css
>
> > it tries:
>
> >    localhost:3000/css/basic.css
>
> > which doesn't exist.
>
> What URL are you accessing?
>
> Ifhttp://localhost:3000/orhttp://localhost:3000/index.htmlthen that sounds entirely expected.
>
> Ifhttp://localhost:3000/home/orhttp://localhost:3000/home/index.htmlthen it should be working correctly, assuming you've set up a route to serve /home/ and/or /home/index.html.

Ryan Schmidt

unread,
Jan 22, 2012, 3:18:16 AM1/22/12
to nod...@googlegroups.com

On Jan 21, 2012, at 20:58, drk wrote:

> aah!.. I was writing localhost:3000/home, which loads only the
> index.html file.
>
> but by writing localhost:3000/home/ it loads everything!
>
> Why does writing localhost:3000/home just loads the html file?

More or less, because that's how web sites work. :) When you write a link like "./css/basic.css", or equivalently "css/basic.css", it means take the current page's URL up to the last "/", then append "css/basic.css" and load that. So if you request "http://localhost:3000/home", the URL up to the last "/" is "http://localhost:3000/", and then it appends "css/basic.css" to get "http://localhost:3000/css/basic.css".

Either write your links as absolute links so it doesn't matter what the current page's URL is (i.e. "/home/css/basic.css"), or ensure that there is only one URL that actually loads any given page, and make sure the relative links work from that page. For example, if you want "/home/" to be the canonical URL, then make it so that if the user requests "/home" it issues an http redirect to "/home/". If you were to serve static files with a web server like Apache, it would issue such a redirect for you automatically, but this is node, where you write the server yourself to do whatever you want it to do. Or perhaps there is a module you can add to do that, or a flag you can add when you define the static file directory.

drk

unread,
Jan 22, 2012, 1:04:07 PM1/22/12
to nodejs
Ok, didn't know it worked like that. thanks!

How would you do such a redirect? (I'm new to node...)

I tried:

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

app.get('/home', function(request, response, next)
{
if (request.url == '/home')
{
//express.static(__dirname + '/home'); // doesn't work
//return;
}

next();
});

app.use('/home', express.static(__dirname + '/home'));
app.listen(3000);



Dobes

unread,
Jan 23, 2012, 12:35:24 AM1/23/12
to nodejs
On Jan 23, 2:04 am, drk <plferrei...@gmail.com> wrote:
> Ok, didn't know it worked like that. thanks!
>
> How would you do such a redirect? (I'm new to node...)

Use res.redirect():

res.redirect(url[, status])
Redirect to the given url with a default response status of 302.

Search it up in the express docs for more details.

Also, I wonder whether app.use('/home', express.static(...)) is quite
right. The docs don't show any examples of passing a path to
app.use().

drk

unread,
Jan 23, 2012, 7:40:29 PM1/23/12
to nodejs
Thanks, redirect() works great.

Just another question, is it better to do:

app.get('/home', function(request, response, next)
{
if (request.url == '/home')
{
response.redirect('/home/', 302);
return;
}

next();
});

for each redirect, or have a switch in:

app.all('/*', function(request, response, next)
{
// a switch here
});

and deal which all at once?


I don't remember where I see that use of .use(), but it does work.

Dobes

unread,
Jan 24, 2012, 10:40:36 PM1/24/12
to nodejs
On Jan 24, 8:40 am, drk <plferrei...@gmail.com> wrote:
> Thanks, redirect() works great.
>
> Just another question, is it better to do:
>
> app.get('/home', function(request, response, next)
> {
>         if (request.url == '/home')
> });

Probably be clever to make a middleware function like:

function addSlashIfMissing(req, res, next) {
if(req.url.charAt(req.url.length-1) !== '/') {
res.redirect(req.url+'/');
} else {
next();
}
}

Then use it like:

app.get('/home', addSlashIfMissing, function(req, res) {
....
});

> for each redirect, or have a switch in:
>
> app.all('/*', function(request, response, next)
> {
> // a switch here
>
> });

I think this would defeat the purpose of using express, as it exists
to help parse URLs and route them to the right code.

> and deal which all at once?
>
> I don't remember where I see that use of .use(), but it does work.

Ah I looked at the source, it looks like it passes this through to
connect(), it's just not documented in the express docs. Good to
know! Also of note is that it is a prefix math on the url, not an
exact match. I think the other routing functions require an exact
match - so get('/foo') would not match a URL /foo/bar. I'm not sure
if a URL /foo/ would be passed to a route specified as get('/
foo', ...), though.

drk

unread,
Jan 26, 2012, 9:27:16 PM1/26/12
to nodejs
thanks for the help!
Reply all
Reply to author
Forward
0 new messages