NodeJS won't serve static files, even when using express.static - node.js

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>

Related

Express can't upload file, req.files is undefined

I really apologize if I'm leaving something out and am totally stupid, but I've checked and checked over again a number of times, and the file upload functionality is just not working over here. I made a super minimal app to demonstate. Just generated a new express app with the most up-to-date version (3.4.7) and added the least i could to make a file upload work.
Here's my app.js file
/**
* Module dependencies.
*/
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', 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(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/tasks', function(req, res) {
res.render('form');
});
app.post('/tasks', function(req, res) {
console.log(req.files);
res.send('ok');
});
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
exports = module.exports = app;
And here's my form.jade view file:
doctype html
html
head
title Task Upload
body
form(action='/tasks', method='post', enctype='multipart/form-data')
input(name='task', type='file')
input(type='submit')
Everytime I try to upload a file, req.files logs out undefined. Can anyone save me out from this problem?
Add the following in your app.js
app.configure(function(){
app.use(express.methodOverride());
app.use(express.bodyParser({keepExtensions:true,uploadDir:path.join(__dirname,'/files'}));
});
And then try to access as follows;
req.files.task
It is recommended not to use bodyParser, but to simply define the type of handling you want. In your case since its file uploading, you can enable it as follows
app.configure(function(){
app.use(express.methodOverride());
app.use(express.multipart());
});
You can read about why using bodyParser() is not a good idea in the following link.
http://andrewkelley.me/post/do-not-use-bodyparser-with-express-js.html
In Express 4, req.files is no longer available on the req object by default.
To access uploaded files on the req.files object, use multipart-handling middleware like busboy, multer, formidable, multiparty, connect-multiparty,.

Send 404 header from not existent static content when using * route in Express

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

Nodejs & express can't find public folder

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)

How to add my existing views,stylesheets,javascripts to express?

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.

Static views contents on dynamic routes

How come the image file in my classroom.ejs is not showing if I use this
app.configure(function() {
//app.use('/room1',express.static(__dirname+'/public'));
app.use(express.static(__dirname+'/public'));
app.set('views', __dirname + '/public');
});
app.get('/room1/:nickname', function(req, res){
res.render('classroom.ejs', {title: req.params.nickname});
});
If I uncomment the app.use('/room1',express.static(__dirname+'/public'));
It works.
I need the static files to pull from /public regardless of the route and given the fact that its on top,
it should have top priority. I'm using Express 3.0.x
Can you try this:
var path = require('path');
...
app.use(app.router);
app.use('/', express.static(__dirname + '/public'));

Resources