9

I have this piece of code here:

var express = require('express')
  , http = require('http')

var app = express();
var server = app.listen(1344);
var io = require('socket.io').listen(server);


app.use(express.static(__dirname + '/public'));
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({secret: 'secret'}));


app.get('/', function(req, res){
    if(req.session){
        console.log(req.session);
    }
    console.log('ok');

});

The code inside the app.get() callback is not being called. If I comment out the app.use(express.static(__dirname + '/public')) line, then the callaback works. I've tried changing the order, but its like a lottery! I would prefer to know whats going wrong here.

I'm sure this have to do with lack of knowledge from my part on how the middleware is called. Can someone help me understand this problem?

Basically I just want to perform some logic before the files are served and the index.html is load on the browser. By the way placing the app.get() before the app.use(express.static()) line, does not did the trick!

6
  • 1
    Do you have a public/index.html file? Commented Apr 18, 2013 at 20:30
  • 2
    That's why it's broken. Remove it and everything will work. There might be an option like "dir" to disable indexes for folders, but I'm not sure Commented Apr 18, 2013 at 20:44
  • But, if I remove the index.html file. Which file is going to display. Do I have to rename that same file. Cause I want to render what's in the index.html file. Commented Apr 18, 2013 at 20:49
  • 2
    Whatever you send in app.get() will be displayed. Right now it's sending index.html then finishing the response, so it never gets to app.get(). I don't know what you're trying to do but using index.html is not a thing in node. Use a templating system. Commented Apr 18, 2013 at 20:52
  • Ok. So in order to render the index.html, do I have to send it inside the app.get()? How can I achieve that? Inside publc I have the index.html file which have the css and javascript files define in it. With static I was able to load the index.html and subsequently the rest of the files. Is there another workflow recommended, I am new to Node.js so I could be trying to mimic some PHP habits, and getting everything wrong! Commented Apr 18, 2013 at 20:58

3 Answers 3

7

Your static file middleware should go first.

app.use(express.static(__dirname + '/public'));
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({secret: 'secret'}));

And you should be adding a use for app.router as well.

app.use(express.static(__dirname + '/public'));
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({secret: 'secret'}));
app.use(app.router);

Middleware is processed in order for each request. So if you have an index.html in your static files then requests for yourdomain.com/ will never make it to the app.router because they will get served by the static file handler. Delete index.html and then that request will flow through to your app.router.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the response. But if use the mddleware on that order using the app.router, then the files are not served. The code inside app.get() is triggered. I want to execute both the file serving and the code inside app.get().
Static middleware should always be first because you don't need all the middleware above it. For example, parsing cookies, setting up sessions, or user authentication for static assets is pretty stupid.
Ok... I get it. I'm not doing a correct use of statics files. I starting to realize that. I'm thinkink on delete the index.html file, and render that file from the server side. Is that the correct way to do it?
Jonathan is right. Put your static handler first, but remove the index.html from your static files.
what if i want to get to the app.router without deleting index.html ? is there any possibility ?
|
3

Rename your index.html file to something else. It is that simple

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

app.get('/', function(req, res){
    if(req.session){
        console.log(req.session);
    }
    console.log('ok');
    res.sendfile(new_index_file);
});

1 Comment

But then what about my CSS file link in my HTML file? Sending the HTML file standalone doesn't link the CSS file.
0

I believe, you have 3 options here:

1) Mount your app.get('/') route (possibly, using app.router) before static middleware, so that they take precedence. Middleware that is mounted first, processes a matching request first.

2) Use a path prefix for your static paths like app.use('/static', express.static('public'));, so that statics is served from example.com/static/...

3) Want to act smart and shoot yourself in the leg? :) Sometimes people use Accept headers and content negotiation to serve 2 different content types from the same url in different circumstances. You can make your static middleware check for a specific content type in Accept header and process request, only if requests's Accept header wants a proper type. Otherwise, it will pass the processing down the stream to you / view. You can customise your static middleware content negotiation in req.accepts.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.