Instead of checking in every controller I want to use app.all('*') to check if the user is authenticated and it already works quite well. If the user is logged in I'm just calling next() and if he's not I'm calling another route to display the login page.
So far so good, but it seems that rendering from that middleware callback function somehow messes up my paths, for example the stylesheet doesn't work and when I click on it in the page source I again land on the index page.
To sum it up, this works and displays my styles:
app.get('/', function (req, res) {
res.render('index', { title: 'Account Page' });
});
while this does work partially, it only displayes the HTML without the styles from the stylesheet:
app.all('*', function (req, res) {
app.set('loggedIn', controller.security.authenticationAction(req));
if (app.get('loggedIn')) next(); // go on with '/' route
else res.render('index', { title: 'Index Page' });
});
This also displays the same HTML page (with another title though) just without the styles.
This is my default config in the app.js:
app.all('*', function (req, res) { ... });
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.cookieParser('keykeykey'));
Help!
Your stylesheets are (probably) served by express.static, which is declared after your app.all() route (with Express, whenever you first declare a route, the router middleware is inserted into the middleware chain there-and-then; in fact, using app.use(app.router) is useless most of the time, because Express has already inserted it behind the scenes).
Because requests are processed by middleware in order of their declaration, your app.all gets to handle the requests for static resources as well. Try moving the static middleware to before your app.all:
app.use(express.static(path.join(__dirname, 'public')));
app.all('*', function (req, res) { ... });
By the way, express.favicon() would probably give similar issues, and if you want to use any of the services provided by express.bodyParser or express.cookieParser etc., the same applies again).
Related
when I enter in http://localhost/client, display 404.
app.get('/client', function(req, res) {
...
ejs.render('any template', {});
...
res.end();
});
app.get('*', function(req, res) {
console.log('404');
...
});
but if I remove "ejs.render" and put res.end('any html') works.
How can i use "ejs.render" and not call 404? Thanks. It's a bug.
You need to set ejs for use EJS with express.
The Express application generator uses Jade as its default, but it also supports several others (Like ejs, pug, etc).
For example:
var express = require('express');
var app = express();
// set the view engine to ejs
app.set('view engine', 'ejs');
// use res.render to load up an ejs view file
// index page
app.get('/client', function(req, res) {
res.render('pages/index'); //does not needs ejs extension
});
app.get('*', function(req, res){
res.send('what???', 404);
});
app.listen(8080);
console.log('8080 is the magic port');
When you make a request to the home page, the index.ejs file will be rendered as HTML.
See the official documentation here.
Within my "views" folder, i have another folder inside called "partials" that has other html files i'd like to render.
I thought it'd be self explanatory but searching through google I can't find the answer to this, but I'd like to render a file within the subdirectory as well.
I'm sure the answer is rather simple but I can't seem to find it..
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');
app.engine('html', require('ejs').renderFile);
var router = express.Router();
//This Works
router.get('/', function(req, res, next) {
res.render('index');
});
//This Works
router.get('/about', function(req, res, next) {
res.render('about');
});
//This Does NOT Work, How do I get this to work?
router.get('/partials/navbar', function(req, res, next) {
res.render('/partials/navbar');
});
Maybe just remove the first / from res.render('/partials/navbar')
I'm trying to set some response-specific variables, and I'm getting undefined for res.locals when I log it from within my middleware, but it returns the function just fine if I log it from within a route function.
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(function (res, req, next) {
console.log("res.locals from app.use middleware: ", res.locals);
// res.locals.boom = 'nice';
// res.locals.zoom = 'yeah!';
next();
});
app.use(app.router);
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
Any ideas?
You have your request & response objects backwards. Obviously if you know the difference in your code, naming doesn't matter, but best to keep things named correctly.
app.use( function (request, response, next) {
// stuff
});
I can't recall off the top of my head, but I believe you want:
request.app.locals;
using my example above. Again, not 100% sure. You can always console out the request object to check.
The app.locals object is a JavaScript Function, which when invoked with an object will merge properties into itself, providing a simple way to expose existing objects as local variables.
app.locals({
title: 'My App',
phone: '1-250-858-9990',
email: 'me#myapp.com'
});
app.locals.title
// => 'My App'
app.locals.email
// => 'me#myapp.com'
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 a 2 routes, the first for an API and the second is a catch all which shows an html page. Now, even if I make a request to .../api/... via a browser, and see the "Invalid" - the second route, ie "called unnecessarily" still gets executed. I'm confused as to why the second route is called since it's already gone via the first route.
// api route
app.get("/api/appname/stuff_settings/:setting", function(req, res) {
// do api stuff
res.send(500, 'Invalid');
});
app.engine('.html', require('ejs').__express);
app.set('views', __dirname + '/views');
app.set('view engine', 'html');
// catch all route
app.use(express.static(path.join(__dirname, 'public')));
app.get('*', function(req, res){
res.render('index', {
console.log("called unnecessarily");
});
});
Do console.log(req.url); in the catch all route my money is on favicon.ico.