I'm trying to learn about Node.js and I have written a simple Node.js page with express and ejs by following a guide at Lynda.com. I have the page hosted on an Amazon AWS server and have Nginx installed. I can access the page at IP:3000 when I'm running the node app. I have also set up Nginx following several different guides to redirect the servers IP/ to port 3000. However when I try and access the page at IP/ none of the images or the CSS show up.
I have set up some webpages in the past for school using Ruby on Rails and I'm assuming that this is a development vs production issue. Most guides/instructions I find just show setting up Nginx for a simple hello world app without any images or CSS. Can someone direct me to the proper resource to accomplish what I'm trying to do here?
Edit: Here are my app.js and my two routes
app.js
var express = require('express');
var reload = require('reload');
var app = express();
var clientFile = require('./data/clients.json');
var instructionFile = require('./data/instructions.json');
app.set('port', process.env.PORT || 3000);
app.set('clientData', clientFile);
app.set('instructionData', instructionFile);
app.set('view engine', 'ejs');
app.set('views', './views');
app.locals.siteTitle = 'Roux Meetups';
app.use(express.static('./public'));
app.use(require('./routes/index'));
app.use(require('./routes/instructions'));
var server = app.listen(app.get('port'), function() {
console.log('Listening on port ' + app.get('port'));
});
reload(server, app);
var express = require('express');
var router = express.Router();
route 1
router.get('/', function(req, res) {
var clients = req.app.get('clientData');
var clientPhotos = clients.images;
var clientAddresses = clients.sites;
res.render('index', {
pageTitle: 'Home',
clients: clientPhotos,
sites: clientAddresses,
pageID: 'home'
});
});
module.exports = router;
route 2
var express = require('express');
var router = express.Router();
router.get('/instructions', function(req, res) {
var clients = req.app.get('clientData');
var clientPhotos = clients.images;
var clientAddresses = clients.sites;
var instructions = req.app.get('instructionData');
var instructPhotos = instructions.images;
res.render('instructions', {
pageTitle: 'Instructions',
clients: clientPhotos,
sites: clientAddresses,
instructs: instructPhotos,
pageID: 'instructions'
});
});
module.exports = router;
I also have only edited my /etc/nginx/sites-available/default for nginx with the following
server {
listen 80 default_server;
listen[::]:80 default_server;
root /var/www/html;
index index.html index.html index.nginx-devian.html;
server_name _;
location / {
proxy_pass http://localhost:3000;
try_files $uri $uri/ = 404;
}
}
So my issue was that my /etc/nginx/sites-available/default was configured way wrong. I had edited it with garbage and totally forgotten that. Leaving this up though in case anyone else has a similar question. The correct nginx configuration I got from https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-14-04
Related
I know that using .htaccess file can restrict files to be served under .git but how do i acheive the same if i'm using node.js server. I use forever to start/stop the servers.
Below is the code.
const bodyParser = require("body-parser");
var request = require("request");
const dotenv = require('dotenv');
const app = express();
//app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static(__dirname));
app.set('view engine', 'ejs');
dotenv.config();
var environment = process.env.NODE_ENV;
var endpoint = process.env.AUTOMATION_API_ENDPOINT;
var port = process.env.PORT;
console.log('Environment : '+ environment);
console.log('Server Port : '+ port);
console.log('BackEnd server Endpoint : '+ endpoint);
var supplierId = null;
var supplyApiEndpoint = null;
app.get("/", function(req,res,next){
var env=null;
var url = endpoint+'/v1/supply/qa/env';
require('http').get(url, (resp) => {
resp.setEncoding('utf8');
resp.on('data', function (response) {
var body = JSON.parse(response);
var supplyApiEndpoint = body.endpoint;
console.log("Endpoint: "+supplyApiEndpoint);
res.render('index',{env: supplyApiEndpoint});
});
});
})```
The forever is a tool for ensuring that a given script runs continuously and not a web framework.
To serve your files you will need to use a web framework like express and you will be able to ignore some directories serving only the files you need, for example, to serve your views directory:
app.set('views', path.join(__dirname, '/yourViewDirectory'));
or adding some rules using regex to ignore the files:
app.use([/^\/public\/secure($|\/)/, /(.*)\.js\.map$/, '/public'], express.static(__dirname + '/public'));
You can use other node.js web frameworks to do the same as fastify or koa.
Working with express Router for getting for the first time.
This is my route.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.send('home page');
});
module.exports = router;
This is my index.js
var express = require('express');
var app = express();
var router=require('./route.js');
app.use('/route',router);
var server = app.listen(process.env.PORT ||8000, function () {
var host = server.address().address;
var port = server.address().port;
console.log("Example app listening at http://%s:%s", host, port)
});
When I open run it in browser it shows:
Cannot GET /
The only URL the code you have written will respond to is:
www.example.com/route/
If you want it to respond to:
www.example.com
then change to the following in your index.js file:
app.use('/', router);
You should replace
app.use('/route',router); with app.use('/', router);
As I may see you have created default route in app.use as /route
you must not have added that using app.use('/') would be enough instead of creating another route for that
Thanks.
I'm trying to block certain files in my site from being publicly accessible. For example, if you go to mysite.com/package.json instead of displaying it in the browser i just want to send and error or redirect back to my homepage or something. I feel like this should be easy... but i haven't been able to get anything to work. there isn't anything complicated about the site, and it's running of a fairly simple server.js
var appRoot = __dirname,
express = require('express'),
chalk = require('chalk'),
mongoose = require('mongoose'),
bodyParser = require('body-parser'),
methodOverride = require('method-override'),
path = require('path'),
errorhandler = require('errorhandler'),
os = require('os'),
http = require('http'),
Routes;
// -----------------------------
// Configuration
// -----------------------------
var port, env, logs;
// Switch some vars based on the ENV
if(process.env.NODE_ENV === 'production'){
port = 3000;
env = 'production';
} else {
port = 8080;
env = 'development';
}
// Express Variables
var app = express();
var router = express.Router();
// Use static files in root
app.use(express.static(__dirname));
// API config
app.use(bodyParser.json());
app.use(methodOverride());
app.use(errorhandler({ dumpExceptions: true, showStack: true }));
// Database
mongoose.connect(mydb);
// Routes / API Config
Routes = require(appRoot + '/routes')(app, router, mongoose);
// After all routes don't match ie. refreshing a page, send index.html
app.get('/*', function(req, res) {
res.sendFile(__dirname + '/index-' + env + '.html');
});
app.listen(port);
I was hoping to do something like:
app.get('/package.json', function(){
res.end('Not allowed');
});
or even before i send it the static html index check if they are trying to access a restricted file. Any suggestions, resources etc are welcomed. If you need any more info just ask.
Based on your comment
You should replace this line:
app.use(express.static(__dirname ));
with this:
app.use('/assets', express.static(__dirname + '/assets'));
app.use('/views', express.static(__dirname + '/views'));
I write a simple program which is really unreadable. At first, I didn't know how to use template so I decide, in spite of that, to write html code inside my node.js code.
(solved)
Try something like this
I usually have a project structure like:
lib
node_modules
public (This is where the CSS and page JS goes)
routes
views (This is where you put your EJS templates)
app.js
In your package.json make sure you have included ejs
"ejs": "*"
In app.js (assuming you use express)
var express = require("express");
var app = express();
var routes = require("./routes/routes.js");
//Other setup code
app.use(express.static(__dirname + '/public'));
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
//Here is an example HTTP route
app.get('/home', routes.view_page);
//Other Server code
And then in routes.js
exports.view_page = function (req,res){
var customMessage = "Hello, Node is awesome";
res.render("view", {
msg:customMessage
});
};
I think your .ejs file is fine, this is a very minimal express server that works with your example:
app.js:
var express = require('express');
var app = express();
app.get('/', function (req, res) {
var customMessage = "My Message";
res.render('view.ejs', {msg:customMessage });
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
then use your view.ejs and put it in the sub-folder views/
I'm a noob and working on mean.js boilerplate.
I've created some routes, but I'm having an issue, where, when I navigate to a certain route ('/articles') i get server output like this:
[{"_id":"5553aa4116a2fddc830b0f66","user":{"_id":"5552398fcf7ada7563db68b7","displayName":"Mo
Bazazi"},"__v":0,"content":"WAHATTATA","title":"Fifth
Examples","created":"2015-05-13T19:47:13.905Z"}]
but i want to ge the rendered view, even when I manually type in the route - does anyone have any suggestions?
here part of my express config
use strict';
/**
* Module dependencies.
*/
var fs = require('fs'),
http = require('http'),
https = require('https'),
express = require('express'),
morgan = require('morgan'),
bodyParser = require('body-parser'),
session = require('express-session'),
compress = require('compression'),
methodOverride = require('method-override'),
cookieParser = require('cookie-parser'),
helmet = require('helmet'),
passport = require('passport'),
mongoStore = require('connect-mongo')({
session: session
}),
flash = require('connect-flash'),
config = require('./config'),
consolidate = require('consolidate'),
path = require('path');
module.exports = function(db) {
// Initialize express app
var app = express();
// Globbing model files
config.getGlobbedFiles('./app/models/**/*.js').forEach(function(modelPath) {
require(path.resolve(modelPath));
});
// Setting application local variables
app.locals.title = config.app.title;
app.locals.description = config.app.description;
app.locals.keywords = config.app.keywords;
app.locals.facebookAppId = config.facebook.clientID;
app.locals.jsFiles = config.getJavaScriptAssets();
app.locals.cssFiles = config.getCSSAssets();
// Passing the request url to environment locals
app.use(function(req, res, next) {
res.locals.url = req.protocol + '://' + req.headers.host + req.url;
next();
});
// Should be placed before express.static
app.use(compress({
filter: function(req, res) {
return (/json|text|javascript|css/).test(res.getHeader('Content-Type'));
},
level: 9
}));
// Showing stack errors
app.set('showStackError', true);
// Set swig as the template engine
app.engine('server.view.html', consolidate[config.templateEngine]);
// Set views path and view engine
app.set('view engine', 'server.view.html');
app.set('views', './app/views');
So Claies was right - this is an HTML5 issue - I've been working on this a little and trying to set up a catch all for express config - I've added this section below:
// Setting the app router and static folder
app.use(express.static(path.resolve('./public')));
app.get('/', function(req, res) {
res.render('index');
});
// Globbing routing files
config.getGlobbedFiles('./app/routes/**/*.js').forEach(function(routePath) {
require(path.resolve(routePath))(app);
});
app.get('*', function(req, res) {
res.redirect('/');
});
The problem is that I'm using mean.js boilerplate, and they have custom glob based routing, which doesn't play well with my catchall i.e. my resources wont work properly with the catchall as they are, although they are rerouting to the correct templates - any thoughts?