Rendering html page in ExpressJS - node.js

I get an error trying to render a simple html page using NodeJS and Express 4.10.4, with the following code:
var path = require('path');
var express = require('express');
var logger = require('morgan');
var app = express();
app.set('port', process.env.PORT || 8080);
app.use(express.static(path.join(__dirname, '/client')));
app.set('view engine', 'html');
app.use(logger('dev'));
app.get('*', function (req, res) {
res.sendFile('/index.html');
});
app.use(function (err, req, res, next) {
console.log(err.stack);
res.status(500).send({message: err.message});
});
console.log('Server has started on port: '+ app.get('port'));
My index.html page is within the client folder, it is rendered in my browser but I get the following error:
Error: ENOENT, stat 'c:\index.html'
Has anyone an idea what's the issue?

The error code 'ENOENT' is a unix error code indicating absence of file.
Check here: http://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/Errors/unix_system_errors.html
I'll advise you use sendFile method of express response with the options and callback stated in the API here: http://expressjs.com/api.html#res.sendFile. Use the options object literal to indicate the location of the html file. See sample below. At first request there is no error. At subsequent requests, the callback will receive an error with response status code 304 - read about what this means.
See below for an amendment to your code and see if it helps you.
var path = require('path');
var express = require('express');
var logger = require('morgan');
var app = express();
app.set('port', process.env.PORT || 9090);
app.use(express.static(path.join(__dirname, '/client')));
app.set('view engine', 'html');
app.use(logger('dev'));
app.get('*', function (req, res) {
var options = {
root: __dirname + '/client/'
};
res.sendFile('/index.html', options, function (err) {
if (err) {
console.log('Error in res : %s, status code: %s', err, res.statusCode);
res.status(err.status).end();
}
else {
console.log('Sent: ', 'index.html');
}
});
});
app.use(function (err, req, res, next) {
console.log('error stack is here : ' + err.stack);
res.status(500).send({message: err.message});
});
app.listen(app.get('port'), function() {
console.log('Server has started on port: '+ app.get('port'));
});

Related

ExpressJS setting up SEO friendly route

I am new to NodeJS and I am experiencing a problem while setting up my routes. I am using i18next, i18next-express-middleware and i18next-node-fs-backend in order to create a multilingual test website.
I would like my URL to look like the following depending on the selected language:
/fr/index, for french,
/en/index, for english,
/jp/index, for japanese.
I am currently facing at least one problem. The default route does not send me to the correct URL. I am always directed to /.
Here is my server.js file:
'use strict';
var debug = require('debug');
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var i18next = require('i18next');
var i18nextMiddleware = require('i18next-express-middleware');
var backend = require('i18next-node-fs-backend');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
i18next
.use(backend)
.use(i18nextMiddleware.LanguageDetector)
.init({
backend: {
loadPath: __dirname + '/locales/{{lng}}/{{ns}}.json',
addPath: __dirname + '/locales/{{lng}}/{{ns}}.missing.json'
},
ns: ["ns.common"],
defaultNS: "ns.common",
fallbackNS: "ns.common",
fallbackLng: 'en',
preload: ['en', 'fr', 'jp'],
saveMissing: true,
removeLngFromUrl: false,
detection: {
order: ['path', 'session', 'querystring', 'cookie', 'header']
},
});
app.use(i18nextMiddleware.handle(i18next));
// 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('/', routes);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function () {
debug('Express server listening on port ' + server.address().port);
});
Here is my index.js file:
'use strict';
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/:lng', function (req, res) {
res.header("Content-Type", "text/html; charset=utf-8");
res.render('index', {});
});
module.exports = router;
The project is articulated as follows:
locales
|_en
ns.common.json
|_fr
ns.common.json
|_jp
ns.common.json
public
|_fonts
|_images
|_javascripts
|_stylesheets
routes
index.js
user.js
views
server.js
Everything is working fine if I enter manually the URL.
Can someone help me detect what is wrong in my code?
Thanks in advance for your answers.
Edit
As pointed out by Kishan, I use the following code, in order to redirect users to the correct locale. Thus, I am using a cookie to store the locale of a user. I ddo not know if it is a safe nor the most optimized way of doing things, but it works.
Here is the index file:
'use strict';
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function (req, res) {
res.redirect(req.cookies.locale + '/index');
});
router.get('/:lng/index', function (req, res) {
res.header("Content-Type", "text/html; charset=utf-8");
res.render('index', {});
});
/* Change locale */
router.post('/locale', function (req, res) {
res.cookie('locale', req.body.locale, { maxAge: 900000, httpOnly: true });
res.json({ status: 'success', redirect: '/' + req.body.locale + '/index'});
});
module.exports = router;
You need to add a route for / (root) in the index.js.
In the above code, the route gets into index.js but not find the path for /(root).
So add the route like...
router.get('/', function (req, res) {
// YOUR LOGIC
});
in your index.js.

Change default file extension for vash from .vash to .html for vs2015 syntax highlighting

How do you change the default file extension for Vash? I would like syntax highlighting in Visual Studio 2015, so I want to change the extension from .vash to .html.
I read that I should be able to do something like:
app.engine("html", require("vash").__express);
But I can't figure out the syntax, or I have the commands in the wrong order.
I have the code working with .vash files, but if I try to change to .html, I get the following error. I have confirmed that there does exist an index.html file in that folder.
Failed to lookup view "index" in views directory IQuestions.FrontEnd\views"
var http = require("http");
var express = require("express");
var path = require("path");
var logger = require("morgan");
var cookieParser = require("cookie-parser");
var bodyParser = require("body-parser");
var routes = require("./routes/index");
var users = require("./routes/users");
var app = express();
// view engine setup
app.set("views", path.join(__dirname, "views"));
app.engine("html", require("vash").__express);
app.set("view engine", "vash");
app.set("port", process.env.PORT || 3000);
app.use(logger("dev"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(require("stylus").middleware(path.join(__dirname, "public")));
app.use(express.static(path.join(__dirname, "public")));
app.use("/", routes);
app.use("/users", users);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error("Not Found");
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get("env") === "development") {
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render("error", {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render("error", {
message: err.message,
error: {}
});
});
module.exports = app;
http.createServer(app).listen(app.get("port"), function () {
console.log("Express server listening on port " + app.get("port"));
});
Try this
app.set('view engine', 'html');
app.engine("html", require('vash').__express);

routing node.js and express

I'm having a problem routing in express 4. I was following the example, but it isn't loading. I'm just getting a spinning wheel.
How do you do routing in express version 4?
app.js:
var express = require('express');
var http = require('http');
var app = express();
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
var port = (process.env.PORT || process.env.VCAP_APP_PORT || 5000);
app.use('/birds', require('./controller/bird'));
http.createServer(function (req, res) {
//res.writeHead(200, {'Content-Type': 'text/plain'});
//res.end('Hello World!\n');
}).listen(port);
console.log('Server running at http://127.0.0.1:'+port);
bird.js:
var express = require('express');
var router = express.Router();
// middleware specific to this router
router.use(function timeLog(req, res, next) {
console.log('Time: ', Date.now());
next();
});
// define the home page route
router.get('/', function(req, res) {
res.send('Birds home page');
});
// define the about route
router.get('/about', function(req, res) {
res.send('About birds');
});
module.exports = router;
You're not calling the app.listen() function. Instead of the http.createServer one, you should invoke the Express function.
Please, take a look at a basic example.
Relevant code:
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
Edit: as slebetman wrote in the comment, the more general way for it is:
http.createServer(app).listen(port, function(){
console.log('now listening on port ' + port);
});

Node.js post method is failing with 500 error

I am new to node.js. I am developing node js application using VS 2015. Below is my server code (app.js)
In one of routes (trains.js) I defined a simple post method like below. Thing is it is working fine from localhost. But once I deploy to azure websites, POST method is throwing Internal server error.
Can some one help me with this? Please let me know if you need any further details.
//Here is my app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var socketio = require('socket.io');
var global = require('./routes/globals.js');
GLOBAL._ = require('lodash');
GLOBAL.KEY = 'xxxxxxxxxxxxxxxxxxxxxx';
var availability = require('./routes/availability');
var fare = require('./routes/fare');
var stations = require('./routes/stations');
var pnr = require('./routes/pnr');
var route = require('./routes/route');
var trains = require('./routes/trains');
var app = express();
app.socket = socketio();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cookieParser());
app.use(require('stylus').middleware(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
app.set('port', process.env.PORT || 3000);
app.use('/availability', availability);
app.use('/fare', fare);
app.use('/stations', stations);
app.use('/pnr', pnr);
app.use('/route', route);
app.use('/trains', trains);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
app.socket.on('connection', function (socket) {
socket.on('message', function (msg) {
console.log('Message Received: ', msg);
socket.broadcast.emit('message', msg);
});
});
global.io = app.socket;
module.exports = app;
//Here is my train.js
var express = require('express');
var http = require('http');
var router = express.Router();
var utils = require("./utils.js");
var global = require('./globals.js');
router.get('/', function (req, res) {
var options = {
host: 'www.xxxxxxx.com',
path: '/test/xxxxxx/'
};
var parameters = {
fscode : 'xxxx',
tscode: 'xxxx',
//date: '',
//'class': '',
//orderby: '',
format: 'json',
pbapikey: '9xxxxxxxxa'
};
options.path += utils.getQueryString(parameters);
options.path += "pbapisign/" + utils.getHmacSHA1Signature(parameters);
callback = function (response) {
var data = "";
response.on('data', function (chunk) {
data += chunk;
});
response.on('end', function () {
console.log(data);
res.send(data + "<h1>" + utils.hello() + "</h1>");
});
}
http.request(options, callback).on('error', function (error) {
console.log(error);
res.status(400).send(error.Message)
}).end();
});
router.post('/check', function (req, res) {
// console.log('Request -', req);
// console.log('Response -', res);
var data = {
request : "HELLO",
response: "VAMSI"
}
global.io.sockets.emit('NEW_CONTACT', data);
res.status(200).send('NEW DATA').end();
});
module.exports = router;
It seems that your code has not any obvious bug.
So if you can share some information for more detail, such as for error or deployment, I think it's helpful for investigating the issue.
Meanwhile, please try to install NTVS for your VS2015 and follow the wiki page Advanced Debugging - Remote Debugging on Windows Azure to debug your application.

How can I use director as router in expressjs

I want to use express.js with Flatiron's director (router) and Resourceful (ODM) because I need like the benefits of routing tables and clean multi-db schemas with validation.
The reason why I now completly switch to Flatiron is, is because I think it needs some more time and there is not much doc material.
However, that is the current way I use director in express:
var express = require('express')
, director = require('director');
function hello(){
console.log('Success');
}
var router = new director.http.Router({
'/': {
get: hello
}
});
Unfortunatly this doesn't work and gives me just a "Cannot GET /"
So what's to do?
var express = require('express')
, director = require('director')
, http = require('http');
var app = express();
var hello = function () {
this.res.send(200, 'Hello World!');
};
var router = new director.http.Router({
'/': {
get: hello
}
});
var middleware = function (req, res, next) {
router.dispatch(req, res, function (err) {
if (err == undefined || err) next();
});
};
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.bodyParser());
app.use(middleware);
app.use(express.static(__dirname + '/public'));
});
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
There is a sample app using express, resourceful and director here.
If you have more doubts, you can ask them in our IRC room #nodejitsu on freenode.
First, in order to use director you need to wrap it up as a middleware and pass it to express, like so:
app.use(function (req, res, next) {
router.dispatch(req, res, function (err) {
if (err) {
// handle errors however you like. This one is probably not important.
}
next();
});
};
Aside from that: You don't need director to use resourceful, and express has its own router (so you may not even need/want director).

Resources