My node.js app can't find the public folder. I've tried using connect static and express static from this answer: static files with express.js and also this answer: File not found in Node.js
But I still can't get it working. I get the content of the page I try to display, but not any of the links to css and js files.
Any ideas?
This is my app.js file.
var express = require('express'),
post = require('./routes/posts'),
web = require('./routes/web'),
http = require('http'),
stylus = require('stylus'),
nib = require('nib'),
path = require('path');
var app = express();
function compile(str, path) {
return stylus(str).set('filename', path).use(nib());
}
app.configure(function () {
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.multipart());
app.use(app.router);
app.use(stylus.middleware({src: __dirname + '/public', compile: compile}));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.bodyParser({ keepExtensions: true, uploadDir: __dirname + '/upload/photos' }));
});
//app.use(app.router);
//Web
app.get('/', web.frontPage);
app.post('/posts', post.findAllPosts);
app.post('/posts/:id', post.findPostById);
app.post('/postAdd', post.addPost);
app.put('/posts/:id', post.updatePost);
app.delete('/posts/:id', post.deletePost);
app.get('*', function(req, res){
res.render('404');
});
http.createServer(app).listen(80);
console.log('Listening on port 80...');
Your problem is caused by this:
app.get('*', function(req, res){
res.render('404');
});
Because you're declaring the app.router middleware (which handles that catch-all route) before the static middleware, the router gets all the requests for static files too, and if they aren't handled by any of your other routes, it will generate a 404.
The solution would be to move the static middleware to before the router. The same also needs to be applied to the Stylus middleware and the bodyParser middleware, to make sure they are called before your routes:
app.use(stylus.middleware({src: __dirname + '/public', compile: compile}));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.bodyParser({ keepExtensions: true, uploadDir: __dirname + '/upload/photos' }));
app.use(app.router);
(although it seems that you can skip the bodyParser middleware, since you're using the json, urlencoded and multipart middlewares already; the bodyParser middleware is just a very thin wrapper around those three)
Related
New to Node.js.
I'm using the VS2015 Express 3 template. How can I write my routing to:
Have a page at "/"
Have a a catch all route that responds with the home page "/"
Doesn't interfere with JS and CSS files
I.e., I tried the following, but then the JS and CSS files in the public directory respond with 404 don't render or execute. I thought that the static files code would handle it, but it does not. It works until I add the block with "*".
var express = require('express');
var routes = require('./routes');
var http = require('http');
var path = require('path');
var app = express();
// 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(app.router);
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('*', function (req, res) {
res.send('/', 404);
});
http.createServer(app).listen(app.get('port'), function () {
console.log('Express server listening on port ' + app.get('port'));
});
The solution, as suggested by jfriend00, is to add the following line below app.get('/', routes.index):
app.use(routes.index);
As my question in Order of router precedence in express.js. I know that the order of express.js is first come first serve. But as code bellows, I don't understand that why the '__dirname' has declared and fixed in above of other code but whaterver I call javascript from ./public/abc.js, the app return a HTML markup of mainpage.
My pages include some javascript and it cannot be loaded. The server return 100% HTML
I am using express generator and folders is structured follows.
NodeJS
var routes = require('./routes/index');
var api = require('./routes/api');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/api', api);
app.use('/users', users);
app.use('/:shopName', function(req, res, next) {
req.shopName = req.params.shopName;
next();
}, routes);
app.use('/', function(req, res) {
res.render('index', {
title: 'MainPage'
});
});
Client Javascript put in script tags like
<script type="text/javascript" src='./public/javascripts/Crypto/crytoUtils.js'></script>
The browser send out error "Uncaught SyntaxError: Unexpected token < cryptoUtils.js " in console and when I click in a link, I see the mainpage HTML markup..
Help me solve the problem ... pls. Thank
The path to the js file should be ./abc.js, public is left out unless you set that as the root for static files using:
app.use('/public', express.static(path.join(__dirname, 'public')));
To be clear, I suggest NOT using the above code, and instead modify your url in the script tag src attribute to appropriately target the file at it's location of /javascripts/Crypto/crytoUtils.js
The problem is static files(css,js) only working on one route but not others.For template I am using handlebar, here is my code snippets :
var express = require('express'),
........
exphbs = require('express-handlebars');
auth = require('./routes/auth')(Account);
.........
app.use(express.static(__dirname + '/public'));
app.engine('handlebars', exphbs({defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
app.use('/auth', auth); //static files not working
app.get('/', function(req, res) { // static files working
res.render('index');
});
for /auth route, I am getting 404 status
I fixed my problem using absolute url in templates
I'v got express app like this.
var express = require('express');
var http = require('http');
var path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(app.router);
app.get('*', function(res,req) {
req.render('index', {title: "Title"});
});
http.createServer(app).listen(app.get('port'), function () {
console.log('Express server listening on port ' + app.get('port'));
});
Because of using app.get('*') request to not existent static files responses with rendered index.ejs file instead of error 404.
Is there any way to fix it without additional conditions in routes?
Just add something like:
app.get(/\/(js|css|img)\/.*/, function (req, res) {
res.send(404);
});
before app.get('*'). Any request to /js that wasn't already matched by the static middleware references an file that does not exist.
Resolved problem by nginx proxying
I have an existing coded frontend i.e views,javascripts,stylesheets (https://github.com/stdrunk/Taskr) and I intend to add this to the express framework so that i can link it to the db.
I added the contents to the public folder. The javascripts in the javascript folder, css in stylesheets, and images in images folder.
Then i changed the code of app.js according to this Render basic HTML view?
Now when run app.js and open the page in the browser i get a stripped version of my original page.
No error comes in the console.
This is my app.js
/**
* Module dependencies.
*/
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
//app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);
app.use(express.static(__dirname + '/public'));
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/users', user.list);
app.get('/home', function (req, res)
{
res.render('index.html');
});
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
You could put all those dirs under a 'public' dir, and then use:
app.use(express.static(__dirname + '/public'));
That way, express will always just send anything requested from those directories, and you won't need to worry about static files at all.
Although, I do recommend keeping something like Apache running on your server to serve static files. Images especially.