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.
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'));
});
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.
this very good tutorial (http://www.danielbaulig.de/socket-ioexpress/) deals on sockets.
And i thinks isn't useful for this case.
So, look this:
app.get("/test.html", app.authenticateUser, function (req, res) {
but where is the app.authenticateUser ?
it is surely he who blocks
So, replaces it by:
app.get("/test.html", function (req, res) {
or modify your app.authenticateUser.
(And use the module fs to read your file, and then, you can res.send(file);)
Don't forget to write .html in your url, else, you have to replace "/test.html" by "/test")
I hope it will help you.
It is because the below code is never called!
app.get("/", function (req, res) {
console.log("get /");
res.redirect("/test.html");
});
As app.use(app.router); is depreciated.All you got to do is write your code above this line
app.use(express.static(__dirname + '/public'));
Should be something like this
app.get("/", function (req, res) {
console.log("get /");
res.redirect("/test.html");
app.use(express.static(__dirname + '/public'));
app.get("/", function (req, res)...
Try this
app.get('/', function (req, res)...
Uri path must be ' single quoted.
Related
This is my current code:
var express = require('express');
app.configure(function(){
app.use(express.static(_settings.c.WEB_PATH + '/public'));
app.use(_mods.web.mware.rawBody);
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.methodOverride());
app.use(express.session({
cookie:{ domain:"."+_settings.c.SITE_DOMAIN, maxAge:1440009999},
secret:'password',
store: r_store,
}));
//other middleware here
});
I want to replace the session part with a custom middleware (in another file).
I will take out that session part and put this in:
var helper = require('helper.js');
app.use(helper.setSession);
In that file, I have this:
var express = require('express');
function setSession(req,res,next){
express.session({
cookie:{ domain:"."+_settings.c.SITE_DOMAIN, maxAge:1440009999},
secret:'password',
store: r_store,
})
next();
};
exports.setSession = setSession;
However, when I run it, the session isn't connecting.I don't know how to debug it.
app.use takes a function (or array of functions) with signature (err, )req, res(, next)
express.session() returns a function like any other middleware. You're never calling the function.
var express = require('express');
function setSession(req, res, next){
express.session({
cookie:{ domain:"."+_settings.c.SITE_DOMAIN, maxAge:1440009999},
secret:'password',
store: r_store,
})(req, res, next);
};
exports.setSession = setSession;
I am a bit confused on how to deal with the Backbone hashes and pushState.
Basically I want
localhost:3004/#/explore
to be
localhost:3004/explore
and
localhost:3004/#/profile/123456
to be
localhost:3004/profile/123456
The first thing was specify all my static directories, which seems to work, since i could access all the files directly via the browser.
app.configure(function(){
app.use("/js", express.static( path.join(__dirname, 'www/js')));
app.use("/assets", express.static( path.join(__dirname, 'www/assets')));
app.use("/style", express.static( path.join(__dirname, 'www/style')));
app.use("/templates", express.static( path.join(__dirname, 'www/templates')));
app.use("/config", express.static( path.join(__dirname, 'www/config')));
app.use(express.favicon());
app.use(express.logger());
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.session({
secret: 'adasdasdasdasdasdasdasdasdasdasd'
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.methodOverride());
app.use(allowCrossDomain);
app.use(app.router);
app.use(express.static(clientDir));
});
This seems to work since I could now navigate to any file from the location bar.
I'm also set up to use pushState
Backbone.history.start({pushState: true});
Where I am confused is in capturing the initial page call and making sure it hits index.html. However it also needs to pass in the directories so BackBones router knows where to go.
A couple unsuccessful attempts include:
app.get("*", function(req, res) {
fs.createReadStream(path.join(clientDir, 'index.html')).pipe(res);
});
another
app.get("*", function(req, res) {
res.redirect('http://localhost:3004#/'+req.url);
});
another
app.get('/', function(req, res){
res.sendfile(path.join(clientDir, 'index.html'));
});
any ideas would be helpful.
I am open to other methods, such as htaccess, etc., although not sure how that would work with heroku deployments.
Looks like this works for me.
app.get('/*', function(req, res){
res.sendfile(path.join(clientDir, 'index.html'));
});
I have done this before... I don't follow what I'm doing wrong this time, but I've been struggling for a couple of hours and now consider myself mentally blocked. The corresponding code:
app.use(express.bodyParser());
app.use(i18next.handle);
app.use(express.methodOverride());
app.use(express.static(__dirname + '/public'));
app.set('views', __dirname + '/views');
app.set('view engine', 'swig');
app.set('view cache', false);
var session_store = new RedisStore({ client : redis_client});
app.use(express.errorHandler({ dumpExceptions : true, showStack : true}));
app.use(express.cookieParser());
app.use(express.session({ store : session_store, secret : SESSION_SECRET, key : "sid" }));
app.use(app.router);
Then when handling requests, here's just an example:
app.get('/session_test', function (req, res, next) {
console.log(req.session); //undefined
});
Connection to redis is working just fine. No errors are shown. Then, when trying to access it from the request, the req.session is undefined. The browser is sending the correct sid.
I'm no expert on the exact flow that occurs during the request, but after debugging, it seems as if the router was being called before the session middleware.
Thanks in advance for any and all the likely help. I will provide any code I can, I'm unsure what might be of your help.
Here's more code.
server.js
//Dependency modules
var express = require('express'),
app = express.createServer(),
//Application dependency modules
settings = require('./settings'), //app settings
routes = require('./routes'), //http routes
rtroutes = require('./rtroutes'); //real time communication routes (io)
var io = require('socket.io').listen(app);
var appWithSettings = settings.setup(io, app);
routes.settings.setup(appWithSettings);
rtroutes.settings.setup(io, appWithSettings);
No routes are added until routes.settings.setup is called. settings (which is the global settings) is a pretty big file. That's where all configuration is done. Settings are not added until settings.setup method is called too. Here's a cut of the file:
//Dependency modules
var express = require('express'),
redis = require('redis'),
//Important configuration values
var SESSION_SECRET = 'some secret thing which doesnt belong to stackoverflow!',
insert_other_variables_here = "lalala";
//Computed general objects
var RedisStore = require('connect-redis')(express),
redis_client = redis.createClient(REDIS_PORT, REDIS_HOST);
exports.setup = function (io, app) {
app.configure(function () {
app.use(express.bodyParser());
app.use(i18next.handle);
app.use(express.methodOverride());
app.use(express.static(__dirname + '/public'));
app.set('views', __dirname + '/views');
app.set('view engine', 'swig');
app.set('view cache', false);
var session_store = new RedisStore({ client : redis_client});
app.use(express.errorHandler({ dumpExceptions : true, showStack : true}));
app.use(express.cookieParser());
console.log("ABOUT TO ADD SESSION STORE MIDDLEWARE");
app.use(express.session({ store : session_store, secret : SESSION_SECRET, key : "sid" }));
console.log("AND NOW ADDED THE SESSION STORE MIDDLEWARE");
app.use(app.router);
});
app.configure('development', function () {
//some things in here, but nothing that affects app. I have commented this
//for debugging and it changed nothing
});
app.configure('production', function () {
//mostly configuration for io and some caching layers, as well as servers info
app.use(express.errorHandler());
app.use(express.logger({ stream : logFile }));
});
app.listen(WEB_PORT);
return {
app : app,
//some other stuff that isn't relevant
}
}
I have 25 routes split in 4 different files (somehow I didn't have a need for session until now, since I was delaying some parts and everything needed was done with Mongoose). Here's an example of how it is being done (with fake names):
routes/index.js
export.settings = require("./settings");
routes/settings.js
exports.setup = function (app_settings) {
require("./route1")(app_settings);
require("./route2")(app_settings);
require("./route3")(app_settings);
};
Here's a stripped out "route1" file ("routes/route1.js"):
module.exports = function (app_settings) {
var app = app_settings.app;
console.log("ABOUT TO ADD ROUTES")
app.get("/signin", function (req, res, next) {
console.log(req.session); //this will be undefined
});
app.get("/register", function (req, res, next) {
});
app.get('/language', function (req, res, next) {
});
app.post('/settings', function (req, res, next) {
});
console.log("ADDED ROUTES NOW!")
}
Whenever you define a route, the router gets automatically inserted into whatever the middleware stack is at the time (subsequent attempts to insert it deliberately will be ignored). Are you sure you aren't defining any routes before you set the session handler?
Forgot to update this: Ebohlman set me in the right track.
It was i18next. When calling one of the init method it sets up routes and it was forcing app.router to be forced into the handle stack sooner. My bad, I didn't realize that part of the code was interacting with the app object and it did.
There was no way the question could have been answered better than how he did with the information I gave, so I am marking his answer as right.
I should try sleeping more v.v
I'm trying to set cookie on express.js but it return undefined.
I've searched many web pages and put express.cookieParser() above app.use(app.router)
but it still can't return the right value.
app.js
app.configure(function(){
var RedisStore = require('connect-redis')(express);
app.use(express.logger());
app.set('view options', { layout: false });
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser({uploadDir: './uploads/tmp'}));
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({ secret: "william", store: new RedisStore }));
//Initialize Passport! Also use passport.session() middleware, to support
//persistent login sessions (recommended).
app.use(passport.initialize());
app.use(passport.session());
//app.router should be after passportjs
app.use(app.router);
app.use(express.compiler({ src: __dirname + '/public', enable: ['less']}));
app.use(express.static(path.join(__dirname, 'public')));
});
app.get('/', function(req, res) {
res.cookie('cart', 'test', {maxAge: 900000, httpOnly: true})
});
app.get('/test', function(req, res) {
res.send('testcookie: ' + req.cookies.cart);
});
the result:
testcookie: undefined
Cookies are set in HTTP Headers. res.cookie() just sets the header for your HTTP result, but doesn't actually send any HTTP. If your code was syntactically correct and it ran, it would actually just sit and not return anything. I also fixed some syntax bugs in your code in this app.get():
app.get('/', function(req, res) {
res.cookie('cart', 'test', {maxAge: 900000, httpOnly: true});
res.send('Check your cookies. One should be in there now');
});
You need to send something out, or at least call res.end(), after setting the cookie. Otherwise all res.cookie() does is add some headers to a list of headers that will be sent out later.
Set cookie name to value, where which may be a string or object converted to JSON. The path option defaults to "/".
res.cookie('name', 'tobi', { domain: '.example.com', path: '/admin', secure: true });
Here is the Link for more detail
http://expressjs.com/api.html#res.cookie
I have something along the lines of the following:
var request = require('request'),
express = require('express');
var app = express.createServer();
var port = process.env.PORT || 8080;
app.configure(function(){
app.set("view options", { layout: false, pretty: true });
app.use(express.favicon());
app.use("/public", express.static(__dirname + '/public'));
}
);
app.listen(port);
// Routes
app.get('/', function(req, resp){
resp.render('index.jade', {pageTitle: 'Some title'});
});
Yet, when I visit /public/myfile.css for example, I still get:
Cannot GET /public/myfile.css
My index.jade templates cannot seem to call the files either
Why is this?
I don't think supplying the path like that is supported:
app.use("/public", express.static(__dirname + '/public'));
Try this, and look for your public files in the root:
app.use(express.static(__dirname + '/public'));
So /public/myfile.css becomes /myfile.css.
Important also is where the position of the app.use(express.static(__dirname + '/public')) statement...
I had a problem when it was nor working when I've accidentally put this in a ./middle-conf.js file which later was imported as var configure = require('./middle-conf) and then the express app was passed into this configure(app).
So the express middle-ware processing order was not not correctly working.
this works fine...
app.use("/public", express.static(__dirname + '/public'));
and in your html pages access it like this..
<script src="/public/yourcodes.js"></script>