Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

node.js app.get not being called

total node.js noobie, started playing with demo codes from various tutorials and websites and I noticed something that I do not understand...

namely, if I have index.html in my /public folder, then

app.get("/", function (req, res) {
    console.log("get /");
    res.redirect("/test.html");
});

is simply never called. As soon as I rename index.html to index2.html then the method is called and I am redirected to /public/test.html

this is what I have:

var io = require('socket.io'),
    express = require('express'),
    MemoryStore = express.session.MemoryStore,
    app = express.createServer(),
    sessionStore = new MemoryStore();

app.configure(function () {
    app.use(express.bodyParser());
    app.use(express.cookieParser());
    app.use(express.session({
        store: sessionStore,
        secret: 'secret',
        key: 'express.sid'
    }));
    app.use(express.static(__dirname + '/public'));
});

and the rest is pretty much taken from this tutorial: http://www.danielbaulig.de/socket-ioexpress/

The same issue appears with any other file. If i have /public/test.html, then when I call

http://localhost:8201/test.html

this app.get is not called:

app.get("/test.html", app.authenticateUser, function (req, res) {
    console.log("get /test.html");
    res.redirect("/test2.html");
});

When I remove the test.html then I get forwarded to test2.html...

The reason I am trying to redirect is if the user is not logged in I do not want him to open index.html but rather want to forward him to login.html, which is not possible if index.html exists. The only "solution" is to do it client side which sucks, I don't want index.html to load in the clients browser just to forward him to login.html, the server should, in my oppinion, handle that.

like image 873
Predrag Stojadinović Avatar asked May 17 '12 18:05

Predrag Stojadinović


2 Answers

Problem is your static file middleware app.use(express.static(__dirname + '/public')) is "in front" of your router. When you write

app.configure(function () {
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({
    store: sessionStore,
    secret: 'secret',
    key: 'express.sid'
}));
app.use(express.static(__dirname + '/public'));
});

this is equivalent to

app.configure(function () {
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({
    store: sessionStore,
    secret: 'secret',
    key: 'express.sid'
}));
app.use(express.static(__dirname + '/public'));
app.use(app.router); //Express implicitly appends router middleware!
});

because Express implicitly appends router middleware at the end of stack if you don't add it somewhere explicitly. Now you clearly see that static file middleware is in front of router. If static file is found it is served by app.use(express.static(__dirname + '/public')) and router app.use(app.router) is never called. If you want your request to always pass through router you should put it in front, for example

app.configure(function () {
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({
    store: sessionStore,
    secret: 'secret',
    key: 'express.sid'
}));
app.use(app.router); //Now router comes first and will be executed before static middleware
app.use(express.static(__dirname + '/public'));
});
like image 182
nivkovic Avatar answered Oct 22 '22 00:10

nivkovic


It's because express filters the request before it gets to your code. It finds the file and returns it to the browser.

Solution is either to send an event via socket.io telling the code in user's browser to redirect or move file into private space (outside public directory) and serve it via "fs" as CydGy suggested.

like image 41
Milan Babuškov Avatar answered Oct 21 '22 22:10

Milan Babuškov