I've been struggling with this for weeks now - for some reason, Express works fine for few hours after launching, then it starts ignoring the requests for static files.
It looks something like this:
GET / 304 153ms
GET /js/bootstrap.min.js 200 120000ms
GET /img/guide/0.png 200 120000ms
GET /img/guide/1.png 200 120000ms
GET /img/guide/2.png 200 120000ms
As I look into Chrome's resource browser, the page at /, handled by a normal app.get() function, is working normally and sent to the client - static files aren't.
From the side of a client, the page loads for 2 minutes showing blank white nothingness, then shows the content without any CSS styling or scripts (predictable).
I have no idea what I'm doing wrong, even simplest examples of Express I've found have this problem, and I didn't see it posted anywhere. Maybe it's the order of middleware, I seriously don't even know anymore...
I hope it's something trivial, and I'm just stupid/blind; here's a part of the code:
app = express()
app.set('views', __dirname + '/views')
app.set('view engine', 'jade')
app.use(express.logger('dev'))
app.use(express.cookieParser())
app.use(express.bodyParser())
app.use(express.session({
key: 'express.sid',
secret: 'wewillchangethislater',
store: sessionStore
}))
app.use(passport.initialize())
app.use(passport.session())
app.use(function(req, res, next) {
res.locals.isAjax = false
res.locals.user = req.user
next()
})
app.use(app.router)
app.use(express.static(__dirname + '/public'))
I've seen it happening with much simpler code tho too:
var express = require('express')
var app = express()
app.set('views', __dirname + '/views')
app.set('view engine', 'jade')
app.use(express.logger('dev'))
app.use(function(req, res, next) {
res.locals.isAjax = false
next()
})
app.use(express.static(__dirname + '/public'))
*some routes here*
app.listen(9999)
The rest of the code is in this utterly broken repo: https://github.com/Maxorq/Mikuia/blob/master/www.js
The only thing I found to help in those cases is restarting, which isn't too fun :/
I've seen this behavior with resin server due to configuration
Maybe not the same but might point you in the right direction
see https://stackoverflow.com/questions/22325309/css-and-js-files-hold-the-http-connection-until-timeout-on-resin-4
Related
I am having trouble with a node.js/express application I am trying to run.
When running on localhost, the data I pass to the route is parsed and I am able to use req.body.message successfully. However on my live site, this only returns undefined. Why is this, and how do I fix it?
This is the node.js app I am using on both the localhost and the live server.
const express = require("express");
const cors = require("cors");
const router = express.Router();
const app = express();
router.post("/send", (req, res) => {
res.send(`message is ${req.body.message}`);
});
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use("/", router);
const PORT = 3030;
app.listen(PORT, () => console.log("Server on " + PORT));
If I do a POST with "message":"hello", on my localhost, I get the response with the "message is hello", but on the live server I get "message is undefined".
Any advice appreciated, cheers.
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
Try putting all this middleware before '/send' API end point. Also check console errors that will give you more information about error.
I solved it. When calling the live api, you need to include a trailing slash.
E.g. examplewebsite.com/send will not work. However, examplewebsite.com/send/ will work.
I don't know enough about how servers work to explain this, but it solved my problem. I hope anyone else with this issue can benefit from my finding.
I' using express js app as a web server but all static content is unzipped (js and css files). I tried a couple of solutions like using compression https://github.com/expressjs/compression but can't get is working.
Here is the way I'm doing it (only the part relevant for compression usage):
var app = module.exports = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(morgan('dev'));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use(methodOverride());
app.use(cookieParser());
var cacheTime = 86; // 7 days
app.use(compression());
app.use(express.static(__dirname + '/public',{ maxAge: cacheTime }));
http.createServer(app).listen(app.get('port'), function () {
console.log('Express server listening on port ' + app.get('port'));
});
Express middleware is always processed in order of declaration.
You have this:
app.use(express.static(...));
app.use(compression());
That means that a request is first processed by express.static(), and when it can handle such a request, it will generate a response immediately and the request will never be passed to the compression middleware.
If you swap the order of the middleware, like this:
app.use(compression());
app.use(express.static(...));
All requests will first pass through the compression middleware, which will set up things so responses will get compressed.
I was having trouble settings up a very basic static file sever using express with Node.js. I set up a simple server.js but cannot see any files when I load the URL localhost:9000 in my web browser.
All I see is a page saying: Cannot get /
var express = require('express');
var app = express();
app.use(function(req, res, next) {
next();
});
app.use(express.static(__dirname));
app.listen(9000);
Simply you're exposing nothing. Do you have, for example, an index.html file? Try this:
app.get("/", function(req, res) {
res.sendfile("index.html");
});
Did you go through the NodeSchool workshoppers? They have step-by-step examples that cover this and more.
Here is the workshop for Express.
Here is my solution for the 'static' question in the workshop.
var express = require('express')
var app = express()
app.use(express.static(process.argv[3]||path.join(__dirname, 'public')));
app.use(require('stylus').middleware(__dirname + '/public'));
app.post('/form', function(req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' })
res.end()
})
app.listen(process.argv[2])
Express does not create a directory listing. Even thought it does not list the files in the directory, it does serve them up when hitting them in the web browser.
Point the browser to the actual file:
http://localhost:9000/public/test.html
Originally I found this confusing because I had expected the express server to list directories; when seeing "something"... a page that said "Cannot get /" I assumed that page would normally have a list of files.
I'm developing a directory app where content is rendered server-side depending on some parameters. My directory is a subapp of other app that is running on appache. I use the reverse proxy to redirect to node when needed.
So, my node root route is this: http://myapp.com/directory/
I need to have routes in this format: http://maypp.com/directory/location/category
where,
location and category can be anything! (it's user generated content)
My initial thought was that I would be able to do something like this:
app.get('/:location?/:category?', routes.index);
However, I get the following behavior:
In my routes.index after I render the view I have
console.log('location: ' + req.params.location + ', category: ' + req.params.category);
When I navigate to http://maypp.com/directory/ I get the following:
location: css, category: main.css
GET /components/modernizr/modernizr.js 200 69ms - 48.97kb
GET /components/requirejs/require.js 200 69ms - 80.75kb
And browser output is broken with the following error:
Uncaught SyntaxError: Unexpected token < main.js:1
And the weirdest thing is that main.js contains rendered HTML page instead of my browser-side js modules.
Another test case:
When I navigate to http://maypp.com/directory/loc/cat I get the following:
location: loc, category: cat
location: css, category: main.css
GET /components/modernizr/modernizr.js 200 6ms - 48.97kb
GET /components/requirejs/require.js 200 6ms - 80.75kb
location: js, category: main.js
and same stuff as above on the browser's side.
In my layout.jade I have the following:
script(type="text/javascript", src="/directory/components/requirejs/require.js" data-main="/directory/js/main")
If I have my route defined without second identifier (like this app.get('/:location?', routes.index);), it works fine, but it's not what I need!
====== Answer =========
Moved all of the route handling below static asset handling middleware.
var app = express();
app.set('port', process.env.PORT || 3000);
app.set('view engine', 'jade');
app.set('views', __dirname + '/views');
app.set('view options', {layout: true});
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.responseTime());
app.use(express.errorHandler());
app.use(express.responseTime());
app.use(require('prerender-node'));
app.use(express.static(path.join(__dirname, '../../public')));
app.use(app.router);
var routes = require('./routes')(app);
location: css, category: main.css
This and some of your errors are because your handlers for static content, css, and js are not set up to execute BEFORE app.router. Ordering of middleware in express must be carefully thought through and precise. So first get your middleware order correct so all your static CSs, JS, images, etc are handled before the app.router.
This is driving me insane.
I have a node app with express. It serves up a file called index.ejs.
All I wanna do is import a javascript file on this page (something like jquery). But it won't pull it up, and I'm going nuts (as this should be simple).
On the server side I have this code in a file called app.js:
var express = require('express');
var app = express.createServer();
var hostName = (process.env.VCAP_APP_HOST || 'localhost');
app.listen( process.env.VCAP_APP_PORT || 8000);
app.use(express.static(__dirname + '/public/javascript/'));
//Create the view
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.set('view options', { layout: false });
app.get('/', function(req, res){
res.render('index.ejs', {
item : "document.write('Hello World');"
});
});
In the ejs file, I have this:
<html>
<script>
<%= item %>
</script>
Link
<script type="text/javascript" src="/javascript/jquery.js"></script>
</html>
I can see in the console that the script is not loaded (it shows an error). But for the life of me I can't figure out why.
You need to add a static server to serve the other files you have under '/'. Currently your server is just responding to requests sent to '/' (and views).
Add this line to your express setup before app.get:
// DOCUMENT_ROOT should point to the directory that contains your javascript directory.
app.use(express.static(DOCUMENT_ROOT));
When your client asks for /javascript/jquery.js, your server is going to be looking for /public/javascript/javascript/jquery.js, and I rather doubt it will find it. Setting express.static()'s pathname to __dirname + '/public' should work, assuming that jquery.js is actually located in your_app/public/javascript.